集合框架图
集合接口
- Collection 接口
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。
Collection 接口存储一组不唯一,无序的对象。
- List 接口
List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。
- Set 接口
Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象。Set集合取出元素的方式可以采用:迭代器、增强for
- Map 接口
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
Set和List的区别
-
Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
-
Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
-
List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
-
可变对象用作Set元素,当修改对象的属性后,可能造成问题。Set对象的元素存储的位置与它的一些属性有关,改动则可能找不到位置。
集合实现类
- LinkedList
该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。
LinkedList 查找效率低。 - Vector
该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。 - ArrayList
该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。 - HashSet
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。HashSet相当于只使用了HashMap的键值那一部分来存储数据,Value那一部分摒弃了。 - LinkedHashSet
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。计算哈希值,哈希值求余%某个值假定16,然后分为16个链表进行存储。 - TreeSet
该类实现了Set接口,可以实现排序等功能。关于 TreeSet 的排序实现,如果是集合中对象是自定义的或者说其他系统定义的类没有实现Comparable 接口,则不能实现 TreeSet 的排序,会报类型转换(转向 Comparable 接口)错误。换句话说要添加到 TreeSet 集合中的对象的类型必须实现了 Comparable 接口。 - HashMap
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的(哈希码)HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。 - TreeMap
继承了AbstractMap,TreeMap 子类是允许 key 进行排序的操作子类,其本身在操作的时候将按照 key 进行排序,另外,key 中的内容可以为任意的对象,但是要求对象所在的类必须实现 Comparable 接口。 - LinkedHashMap
继承于HashMap,使用元素的自然顺序对元素进行排序.
ArrayList 和 LinkedList 的区别
ArrayList 是 List 接口的一种实现,它是使用数组来实现的。
LinkedList 是 List 接口的一种实现,它是使用链表来实现的。
ArrayList 遍历和查找元素比较快。LinkedList 遍历和查找元素比较慢。
ArrayList 添加、删除元素比较慢。LinkedList 添加、删除元素比较快。
迭代器
- ListIterator 继承了 Iterator,以允许双向遍历列表和修改元素。
- Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合
迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
比较器
TreeSet和TreeMap的按照排序顺序来存储元素. 然而,这是通过比较器来精确定义按照什么样的排序顺序。
- Comparable 自然排序
Comparable 在 java.lang 包下,是一个接口,内部只有一个方法 compareTo():
Comparable 可以让实现它的类的对象进行比较,具体的比较规则是按照 compareTo 方法中的规则进行。这种顺序称为 自然顺序。
compareTo 方法的返回值有三种情况:
e1.compareTo(e2) > 0 返回值大于0,即 e1 > e2
e1.compareTo(e2) = 0 即 e1 = e2
e1.compareTo(e2) < 0 即 e1 < e2
注意:
- 重写 compareTo 方法时应该注意 e.compareTo(null) 的情况
- e1.compareTo(e2) == 0 的结果要和 e1.equals(e2) 一致
- Comparator 定制排序
使用方式主要分三步:
1、创建一个 Comparator 接口的实现类,并赋值给一个对象
2、在 compare 方法中针对自定义类写排序规则
3、将 Comparator 对象作为参数传递给 排序类的某个方法
4、向排序类中添加 compare 方法中使用的自定义类
总结
-
集合框架的类和接口均在java.util包中。
-
任何对象没有使用泛型之前会自动转换Object类型,使用泛型之后不用强制转换,否则加入集合类后,自动转变为Object类型,取出的时候需要进行强制类型转换
-
在只遍历 key 的时候使用 keySet(), 在只遍历 value 的是使用 values() 方法, 在遍历 key-value 的时候使用 entrySet() 是比较合理的选择。