- 为了保存数量不确定、以及保存具有映射关系的数据,Java提供了集合类这一工具类。位于java.util包下。
- 数组即可保存基本数据类型的值,也可以保存对象。但那时集合只能保存对象。
- Java集合类主要由两个接口派生而出,Collection和Map。其中Set(无序集合)、List(有序集合)是Collection接口派生的两个接口,Queue是Java提供的队列实现,也由Collection派生而出。Map保存的每项数据都是key–value对,key不可重复。
- 对于Set、List、Queue、Map四种集合常用的实现类有:HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap、TreeMap。
-
Collection接口操作集合元素的方法:
boolean add(Object o); //向集合里添加一个元素
boolean addAll(Collection c); //把集合c里的所有元素添加到指定的集合里
void clear(); //清除集合里的所有元素
boolean contains(Object o); //集合里是否包含指定元素
boolean containsAll(Collection c); //集合里是否包含集合c里的所有元素
boolean isEmpty(); //集合是否为空
boolean iterator(); //返回一个iterator对象,用于遍历集合里的元素
boolean remove(Object o); //删除指定元素,多个时只删除第一个
boolean removeAll(Collection c); //删除集合c里包含的所有元素
boolean retainAll(Collection c); //删除集合里不包含c的元素‘
int size(); //返回集合里元素的个数
Object[] toArray(); //把集合转为数组 - 使用println()方法直接输出集合对象时,将输出[v1,v2,…],因为所有的collection实现类都重写了toString方法。
-
Iterator接口用于遍历(迭代访问)Collection集合中的元素,Iterator对象也被称为迭代器。使用迭代器访问Collection集合元素时,集合里的元素不可改变,只有通过Iterator的remove()方法删除上一次next()返回的集合元素才可以。
boolean hasNext();//如果被迭代的集合元素没有被遍历完,返回true
Object next(); //返回集合里的下一个元素
void remone(); //删除集合里上一次next方法返回的元素
void forEachRemaining(Consumer action); //可使用Lambda表达式来遍历集合元素 - Set集合不允许包含相同的元素,如果添加一个已有的元素,add()方法返回flase,新元素不会加入Set集合。
- HashSet是Set接口的一种典型实现,按照Hash算法来存储集合中的元素,具有很好的存取和查找性能。特点:
- 不能保证元素的排列顺序。
- 不是同步的,如果多线程同时访问一个HashSet,必须通过代码来保证其同步。
- 集合元素值可以为null。
- HashSet有一个子类LinkedHashSet,该类也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,遍历该集合的元素时,将会按照元素的添加顺序来访问元素。它的性能略低于HashSet,因为它需要维护元素的插入顺序,但在迭代访问时性能好,因为它用链表维护内部顺序。
- TreeSet是SortedSet接口的实现类,可以确保集合元素处于排序状态。该类采用红黑树的数据结构来存储集合元素。
- TreeSet排序规则:
- 自然排序,调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后按升序排序。
- 定制排序,创建TreeSet集合对象的时候,提供一个Comparator对象与该TreeSet集合关联,由该Comparator对象负责集合元素的逻辑排序。
- EnumSet是专门为枚举类设计的集合类,EnumSet在内部以向量的形式存储,这种存储形式非常紧凑、高效。所以该类的对象占用内存小,且运行效率高(不允许添加null)。
- List集合代表一个元素有序,可重复的集合,List集合默认按元素添加顺序设置元素的索引。
- ArrayList和Vector是List类的两个典型实现,ArrayList是线程不安全的,Vector是线程安全的,但是Vector是很古老的东西了,尽量不用。
- Queue集合用于模拟队列,是一个先进先出的容器。
- PriorityQueue是一个比较标准的队列实现,因为它保存元素并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序。因此用peek()和poll()方法取出元素时总会取出最小的元素(不允许添加null)。
- Deque接口是Queue接口的子接口,它代表一个双向队列。该接口提供了一个典型实现类:ArrayDeque,它是一个基于数组实现的双端队列。
- LinkedList类是List接口的实现类,同时也实现了Deque接口,可以被当作双端队列使用,因此可以用做栈和队列。
- Map用于保存具有映射关系的数据,key-value其中key的值必须唯一。
- HashMap和Hashtable都是Map接口的典型实现类,Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMap性能较高。Hashtable不允许使用null作为key和value,HashMap允许。
- LinkedHashMap是HashMap的子类,使用双向链表来维护key-value对的次序,该链表负责维护Map的迭代顺序,迭代顺序与插入顺序保持一致。
- Map接口也派生出SortMap接口,TreeMap是这个子接口的实现类,它是一种红黑树的结构,TreeMap存储节点时,根据key对节点进行排序。TreeMap可以保证所有key-value处于有序状态。
- WeakHashMap与HashMap类似,区别在于对对象的引用,WeakHashMap是弱引用,HashMap是强引用。垃圾回收对象后,WeakHashMap会自动删除该key对应的key-value对,而HashMap不会。
- IdentityHashMap实现类,两个key需完全相等才认为相等,HashMap只需要equals()方法返回true,hashCode相等即可。
- EnumMap是一个与枚举类一起使用的Map实现,EnumMap中所有key都必须是单个枚举类的枚举值。