java基础一(集合框架)

(六)、集合框架
特点:
1、用于存储数据的容器。
2、对象封装数据,对象多了也需要存储。集合用于存储对象。
3、对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为集合是可
变长度的。

集合和数组的区别:

1:数组是固定长度的;集合可变长度的。
2:数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据
类型。
3:数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型

集合框架图:
java基础一(集合框架)
从上面的集合框架图可以看到:
1、所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
2、List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以
重复。
3、Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元
素唯一性。
4、Map接口是键-值对象,与Collection接口没有什么关系。

Collection
1,添加
① add 将指定的某一个元素添加到集合中
② addAll 将指定的集合对象一次性添加到集合中

2,修改
① 对集合的修改无非是获取集合中的某一个元素然后再重新赋给新值

3,查询(获取)
① iterator  此方法返回一个迭代器对象,方便用于对集合中的每个元素进行循环获取操作
② contains  是否包含某个元素
③ containsAll  是否包含另一个集合中的所有元素
④ equals  比较两个集合是否相等
⑤ isEmpty  判断一个集合是否为空
⑥ size  获取集合中元素的数量
⑦ retainAll  求和另外一个集合的交集

4,删除
① remove  删除集合中的某一个元素
② removeAll  删除集合中某一个子集(参数为集合对象)
③ clear  清除集合中所有的元素

5,其它
① toArray  返回包含此集合元素的数组对象
② hashcode  返回此集合元素的哈希码

注意:Iterator
Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口如下:

boolean hasNext():判断集合里是否存在下一个元素。如果有,hasNext()方法返回 true。
Object next():返回集合里下一个元素。
void remove():删除集合里上一次next方法返回的元素。

List

List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。
List 本身是 Collection 接口的子接口,具备了 Collection 的所有方法。现在学习
List 体系特有的共性方法,查阅方法发现 List 的特有方法都有索引,这是该集合最大的特点。

List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

(1)、 ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。

ArrayList擅长于随机访问。同时ArrayList是非同步的。
(2)、LinkedList
同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。

由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。

与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(…));

(3)、Vector
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

(4)、Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

Set
Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样允许null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。

Set是一种不包含重复的元素的Collection,无序,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。需要注意的是:虽然Set中元素没有顺序,但是元素在set中的位置是由该元素的HashCode决定的,其具体位置其实是固定的。

(1)、HashSet
HashSet是基于HashMap来实现的,操作很简单,更像是对HashMap做了一次“封装”,而且只使用了HashMap的key来实现各种特性,而HashMap的value始终都是PRESENT。
HashSet不允许重复(HashMap的key不允许重复,如果出现重复就覆盖),允许null值,非线程安全。

(2)、TreeSet
reeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。

注意:TreeSet集合不是通过hashcode和equals函数来比较元素的.它是通过compare或者comparaeTo函数来判断元素是否相等.compare函数通过判断两个对象的id,相同的id判断为重复元素,不会被加入到集合中

遍历(和list相似)
迭代

Set<String> set = new HashSet<String>();
    set.add("a");
    set.add("e");
    set.add("b");
    set.add("c");
    Iterator iterator = set.iterator();
    while(iterator.hasNext()){
        String str = (String) iterator.next();
        System.out.println(str);
    }

foreach:

	for (String str : set) {  
  System.out.println(str);  }

Map集合(键值对、键唯一、值不唯一)

Map 集合存储和 Collection 有着很大不同:
Collection 一次存一个元素;Map 一次存一对元素。
Collection 是单列集合;Map 是双列集合。
Map 中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。
特点:要保证 map 集合中键的唯一性。

(1)、HashMap
 数组方式存储key/value,线程非安全,允许null作为key和value,key不可以重复,value允许重复,不保证元素迭代顺序是按照插入时的顺序,key的hash值是先计算key的hashcode值,然后再进行计算,每次容量扩容会重新计算所以key的hash值,会消耗资源,要求key必须重写equals和hashcode方法
 
方法
1、添加:
V put(K key, V value) (可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null)

putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。

2、删除
  remove() 删除关联对象,指定key对象
  clear() 清空集合对象

3、获取
value get(key) 可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。

4、判断:

boolean isEmpty() 长度为0返回true否则false

boolean containsKey(Object key) 判断集合中是否包含指定的key

boolean containsValue(Object value) 判断集合中是否包含指定的value

4、长度:

Int size()
 
取出 map 集合中所有元素
方式一:keySet()方法:
可以将 map 集合中的键都取出存放到 set 集合中。对 set 集合进行迭代。迭代完
成,再通过 get 方法对获取到的键进行值的获取。

	 //keySet方法
    HashMap<Object,String> hashMap = new HashMap<Object, String>();
    hashMap.put("1","张三");
    hashMap.put("2","李四");
    hashMap.put("4","王五");
    hashMap.put("5","钱六");
    Set keySet = hashMap.keySet();
    Iterator iterator = keySet.iterator();
    while (iterator.hasNext()){
        Object key = iterator.next();
        String value = hashMap.get(key);
        System.out.println(key+":"+value);
    }

方式二:entrySet()方法

//entrySet()方法
	HashMap<Object,String> hashMap = new HashMap<Object, String>();
    hashMap.put("1","张三");
    hashMap.put("2","李四");
    hashMap.put("4","王五");
    hashMap.put("5","钱六");
    Set entrySet = hashMap.entrySet();
    Iterator iterator1 = entrySet.iterator();
    while (iterator1.hasNext()){
        Map.Entry en = (Map.Entry) iterator1.next();
        System.out.println(en.getKey()+":"+en.getValue());
    }

(2)、Hashtable
  Hashtable与HashMap类似,是HashMap的线程安全版,它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢,它继承自Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。

(3)、TreeMap

3.TreeMap

TreeMap 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。

自然排序:TreeMap中所有的key必须实现Comparable接口,并且所有的key都应该是同一个类的对象,否则会报ClassCastException异常。

定制排序:定义TreeMap时,创建一个comparator对象,该对象对所有的treeMap中所有的key值进行排序,采用定制排序的时候不需要TreeMap中所有的key必须实现Comparable接口。

TreeMap判断两个元素相等的标准:两个key通过compareTo()方法返回0,则认为这两个key相等。

如果使用自定义的类来作为TreeMap中的key值,且想让TreeMap能够良好的工作,则必须重写自定义类中的equals()方法,TreeMap中判断相等的标准是:两个key通过equals()方法返回为true,并且通过compareTo()方法比较应该返回为0。

异同:
1.ArrayList和LinkedList

(1)ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
(2)对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针。
(3)对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

2.HashTable与HashMap

相同点:

(1)都实现了Map、Cloneable、java.io.Serializable接口。
(2)都是存储"键值对(key-value)"的散列表,而且都是采用拉链法实现的。

不同点:

(1)历史原因:HashTable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 。
(2)同步性:HashTable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 。
(3)对null值的处理:HashMap的key、value都可为null,HashTable的key、value都不可为null 。
(4)基类不同:HashMap继承于AbstractMap,而Hashtable继承于Dictionary。

3、Collection 和 Collections区别
(1)、java.util.Collection 是一个集合接口(集合类的一个*接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set
(2)、java.util.Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架

4、Iterator和ListIterator区别
(1)ListIterator有add()方法,可以向List中添加对象,而Iterator不能
(2)ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
(3)ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
(4)都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。