1.集合就是一个放数据的容器,准确的说是放数据对象引用的容器。
2.常用集合:
Collection :是一个接口。
1 List :元素有序、可重复、并引入位置下标。
1.1 LinkedList :底层是双向循环链表。增删快、查询慢、线程不安全、效率高。
1.2 ArrayList :底层数据结构是数组。查询快、增删慢、线程不安全、效率高。
1.3 Vector :底层数据结构是数组。查询快、增删慢、线程安全、效率低。
1.3.1 Stack
2 Set :元素无序,不可重复。
2.1 HashSet :无序的,底层数据结构是哈希表。储存对象的时候依赖两个方法hashcode()和equals(),重写hashcode()和equals()即可。
2.1.1 LinkedHashSet :底层数据结构是哈希表和链表组成。链表保证有序,哈希表保证唯一。
2.2 TreeSet :底层数据结构是红黑树。按照自然顺序进行排列,如果是汉字则会按照a-z排序。
Map
1. Hashtable :不可以添加为空,底层数据结构是哈希表,线程安全,效率低。
2. HashMap :可以添加为空,底层数据结构是哈希表,线程不安全,效率高。
3. WeakHashMap:以弱键实现的基于哈希表的Map。
4. TreeMap :底层数据结构是红黑树,有序的,效率比HashMap低。
5. LinkedHashMap:底层数据结构是哈希表和链表组成,链表保证有序,哈希表保证唯一,仅比HashMap慢一点。
3. 注意
1,集合只能存放对象。比如存一个int型数据1放入集合中,其实他是自动转为Integer类后存入的,Java中每一种基本类型都有对应的引用类型。
2,集合存放的是多个对象的引用,对象本身还是放在堆内存中。
3,集合可以存放不同类型,不限数量的数据类型。
4. 遍历方式
1. for循环遍历:遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素。
2. 迭代器遍历,Iterator:每一个具体实现的数据集合,一般都需要提供相应的Iterator。相比传统的for循环,Iterator取缔了显式的遍历计数器,所以基于顺序存储集合的Iterator可以直接按位置访问数据。而基于链式存储集合的Iterator,正常的实现,都是需要保存当前的遍历位置,然后根据当前位置来向前或向后移动指针。
3. foreach循环遍历:foreach内部也是采用了Iterator的方式实现。
5. 各集合之间的对比
List、Set和Map:
List是有序的集合,Set是无序的集合。Map是无序的键值对。
ArrayList和Vector:
都是List的实现类。他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按照位置索引号取出某个元素。
Vector是线程安全的,也就是说他的方法之间是线程同步的,而ArrayList是线程不安全的,他的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好使用ArrayList,因为他不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
ArrayList和LinkedList:
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
对于随机访问的get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
HashSet和TreeSet:
HashSet要比TreeSet的性能要好,因为TreeSet需要额外的红黑树算法来维护集合的次序。所以只有当需要保持排序的Set时候,才会使用TreeSet,否则都应该使用HashSet。
HashSet和HashMap:
都是采用Hash算法来决定元素的存储位置,并通过hash算法来增加集合大小的。其中,最大的区别就是,HashSet实现的Set接口,他不允许有重复的值。HashMap实现的是Map接口,里面存储的是键值对,map中不允许存在重复的key。
HashMap和HashTable:
HashTable是一个线程安全的Map实现,但HashMap是线程不安全的实现,所以HashMap比HashTable的性能高一些;但是如果有多个线程访问同一个Map对象的时候,应该使用HashTable。
HashTable不允许使用null作为key和value,如果视图把null值放入HashTable中会引发NullPointerException异常。但是 HashMap可以使用null作为key或value。Null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。