目录
一、集合是什么
集合可以看做是一种容器,用于存储对象信息,所有集合类位于java.util包下,支持多线程的集合类位于java.util.concurrent包下
Java集合类主要由两个跟接口Collection和Map派生出来的,Collection派生出了三个子接口:List,Set,Queue。Java集合大致也可以分成List,Set,Queue,Map四中接口体系。
List指的是有序可重复集合,可直接根据元素的索引来访问;Set指的是无序不可重复集合,只能根据元素本身来访问;Queue是队列集合;Map指的是储存key-value的集合,可根据元素的key来访问value。
二、Java集合常见接口及实现类
1.Collention接口
2.Set集合
Set不允许存储相同的元素,所以把两个相同元素添加到同一个Set集合,会添加失败,add()返回false。
(1)HashSet
最常用实现类,HashSet按照hash算法存储元素,存取查找性能较好。
特点:
不能保证元素顺序;HashSet不是线程同步的,如果多线程操作HashSet集合,应通过代码保证同步;集合元素值可以为null。
存储原理:
向HashSet集合存储一个元素,HashSet会调用该对象的hashCode()得到hashcode值,然后根据该值决定该对象的存储位置。判断两元素相等的标准:1.通过equals方法比较返回true;2.hashCode()返回值相等;有一个条件不满足,则认为两个对象不相等,可以添加成功。如果两个对象的hashCode()返回值相同,两个对象通过equals比较返回false,HashSet回以链表结构将两个对象保存在同一位置。
查找原理
查找元素时,先计算hashCode的值,然后到该值对应的位置取出元素,这是HashSet速度快的原因。
重写hashCode的基本原则
同一个对象的hashCode方法返回值应该相同;
当两个对象通过equals比较返回true时,两个对象的hashCode返回值应该相等;
对象中用equals方法比较标准的实例变量,用于计算hashCode值。
(2) LinkedHashSet
LinkedHashSet是HashSet的一个子类,具有HashSet的特性,也根据元素的hashCode值来决定元素的存储位置。使用链表维护元素次序,元素顺序和田姐顺序一致。由于LinkedHashSet需要维护元素的插入顺序,性能略低于HashSet。
(3) TreeSet
TreeSet是SortedSet接口的实现类,可以保证元素处于排序状态,采用红黑树存储集合元素。支持两种排序方法:自然排序和定制排序,默认用自然排序。
- 自然排序
TreeSet会调用集合元素的compareTo(Object obj)比较元素的大小,将元素升序排列,即为自然排序。如果将一个对象加入到TreeSet中,必须实现Comparable接口,否则会抛出异常。obj1.compareTo(obj2),如果该方法返回0,两个对象相等,如果返回一个正数,obj1大于obj2,如果返回负数,obj1小于obj2. - 定制排序
通过将对象实现Comparator接口,与TreeSet集合关联,有Comparator对象负责集合元素的排序逻辑。
(4) EnumSet
转为枚举类设计的集合,不允许添加null值。EnumSet的集合元素也是有序的,以枚举值在Enum类内定义顺序来决定集合元素的顺序。
(5) 各个Set实现类的性能分析
HashSet性能比TreeSet性能好(添加,查询时),因为TreeSet需要额外的红黑树算法维护元素的次序,如果需要保持排序的Set使用TreeSet,否则使用HashSet。
LinkedHashSet是HashSet的子类,由于需要链表维护元素的顺序,所以插入删除操作比HashSet慢,但是 遍历比HashSet快。
EnumSet是所有set实现类性能最好的,但只能保存同一个枚举类的枚举值作为集合元素。
以上的Set实现类都是线程不安全的。
3.List集合
List集合代表一个有序,可重复集合,集合中每个元素有对应的顺序索引。List集合默认按照元素的添加顺序设置元素索引,可以通过索引访问对应位置的集合元素。
- ArrayList
是一个动态数组,是List类的典型实现,允许任何符合规则的元素插入,包括null,每个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器元素增加,容器大小也增加。因此向容器 - LinkedList
是List接口的另一个实现,除了可以根据索引访问集合元素外,还实现了Quque接口,可以当做双端队列使用。
实现机制与ArrayList不同,以链表的型式保存集合中的元素,随机访问性能较差,但是插入删除有较好的性能。 - Vector
与ArrayList类似,但是Vector是同步的。 - Stack
继承自Vector,是一个先进后出的堆栈。提供5个额外的方法使Vector被当做堆栈使用。push进栈 pop出栈 peek得到栈顶元素 empty测试堆栈是否为空 search检查一个元素在堆栈的位置 - Iterator接口和ListIterator
Iterator
hasNext():判断集合是否存在下一个元素。有的话hasNext()返回true
Objcet next()返回集合里下一个元素
void remove()删除集合里上一次next方法返回的元素
ListIterator
hasPrevious()判断集合是否存在上一个元素。有则返回true
previous()返回集合的上一个元素
add(Object o)指定位置插入一个元素
ListIterator继承了Iterator,增加了向前迭代的方法,还可以通过add向List添加元素(Iterator只能删除元素)
4.Map集合
Map接口采用键值对<K,V>的存储方式,保存具有映射关系的数据。Map集合保存两组值,一组用于保存Map的key,另一组保存Map的value。key和value可以是任意类型的数据,key不可以重复。
-
HashMap与Hashtable
都是Map接口的两个典型实现,他们之间的关系类似ArrayList和Vector。HashTable是一个古老的Map实现类,提供的方法比较繁琐,有两个区别
1、HashMap线程不安全,HashTable线程安全
2、HashMap可以用Null值为key和value,HashTable不能用null作为key和value。如果把null放进table中,会发生空指针异常。
若想在HashMap和HashTable存储获取对象,作为key的对象必须实现hashCode和equals方法。 -
LinkedHashMap
使用双向链表维护key-value的次序 -
Properties
-
TreeMap
-
各Map的性能否分析