Java集合总的分为两阵营。一个以collection为首(单值元素),另一个则是map为首(键值对)。

List和Set

相同点:
操作数据集合的方法大致相同,例如:add()、remove()、congtains()、size()等
不同点:

  • List元素可重复、元素有序(和添加顺序一致)、元素可为空
  • Set元素不可重复、元素无序、元素可为空

set

HashSet类与LinkedHashSet类

相同点:
同为set的实现类,同时也都是根据hashCode来决定元素存储位置
不同点:
1.HashSet不是同步的,多线程访问同一步HashSet对象时,需要手工同步,集合元素值可以为null,但不重复。
2.LinkedHashSet集合元素有序但不重复。需要维护元素的插入顺序,性能略低于HashSet

HashSet与TreeSet
1.HashSet不能保证元素的排列顺序,TreeSet是SortedSet接口的唯一实现类,可以确保集合元素处于排序状态
2.HashSet底层用的是哈希表,TreeSet采用的数据结构是红黑树
3.HashSet中元素可以是null,但只能有一个,TreeSet不允许放入null

List

ArrayList和Vector实现类
相同点:
都是基于数组实现
不同点:
1.ArrayList是线程不安全,而Vector是线程安全
2.Vector的性能会比ArrayList低,且有很多重复方法
3.Vector提供一个子类Stack,可以挺方便的模拟“栈”这种数据结构(LIFO,后进先出)。
注:Vector现在已不经常使用

LinkedList类,基于链表实现的,且有固定的list方便数据的转换(特点是不可以增加元素,也不可以删除元素)

补充:那么数组和链表会有什么不同?

数组:下标访问,所以访问速度比较快,TC为O(1),插入的时候需要移动数据元素,插入慢。TC为O(n)

链表:插入速度快T(1)。只需要改变指针指向。访问慢O(n),需要从头开始一个一个查找。

MAP

HashMap和TreeMap

HashMap key和value值允许为空,key相同时,前者会覆盖后者,保持最新。

HashMap和HashTable的区别

相同点:
1.基于hash表实现的,每个元素都是key-value对,内部都是通过单向链表解决冲突,容量都会自动增长 (默认16)

不同点:
1. HashMap继承自AbstractMap类,HashTable继承自Dictionary类,
2. HashTable是同步的,适合多线程环境,而HashMap不是,但效率相对较高
3. HashMap允许key和value为null,而HashTable不允许
4. Hash值的使用不同,HashTable直接使用对象的hashcode值,而HashMap重新计算hash值
5. 在Java1.4中引入了HashMap的子类LinkedHashMap,若需要遍历顺序,可以从HashMap转向LinkedHashMap, 而HashTable的顺序是不可预知的
6. HashMap提供对key的Set进行遍历,因此它支持fail-fast机制,而HashTable提供对key的Enumeration进行遍历,不支持fail-fast

HashMap和ConcurrentHashMap的区别

1、HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。
2、ConcurrentHashMap让锁的粒度更精细一些,并发性能更好。

Iterator和ListIterator的区别

相同点:
1. 两者都有hasNext()和next()方法,可以实现顺序向后遍历,ListIterator还有hasPrevious()和previous()方法,可以实现逆序遍历
2. 都有remove()方法可以实现删除对象,ListIterator还有添加方法add()和修改方法set(),可以实现添加和修改对象, Iterator的协议不能确保迭代的次序,所以没有提供add()方法

不同点:
1. ListIterator继承自Iterator接口,然后添加了一些额外的功能
2. Iterator可以遍历Set和List集合,而ListIterator只能遍历List集合
3. ListIterator有nextIndex()和previousIndex()方法,可以定位当前的索引位置,Iterator没有此功能

总结:

  • 集合的长度是可变的,但只能存放引用数据类型的数据,不能存放基本数据类型的数据
  • Collection是集合类的基本接口,其主要的子接口有List和Set,而Map不是其子接口。Collection接口声明所有集合类的核心方法,一般情况下都不会使用Collection接口,而是使用其子类List和Set集合
  • List是有序的Collection,使用List可以精确的控制每个元素插入的位置,也可以通过索引来访问List中的元素。List接口常用的实现类有ArrayList和LinkedList,List集合中允许存放重复的元素
  • Set是一个不包含重复元素的Collection,Set允许包含null元素,但不能包含重复的元素。一般需要重写equals()和hashCode()方法,来区别Set集合中的元素是否相同
  • Set接口常用的子类有HashSet和TreeSet,其中HashSet是按照哈希算法来存取集合中的元素的,其存取的效率高,HashSet类是无序存放元素的,而TreeSet是有序存放元素的,但需要使用Comparable进行排序操作
  • 集合的输出有多种方式,其中,使用Iterator迭代器是标准的输出方式;
  • Map并没有继承Collection接口,可用于保存有映射关系的数据,其提供的是key到value的映射
  • Map接口常用的实现类有HashMap和TreeMap。HashMap类是基于哈希表的Map接口实现,对于元素的删除和添加有着较高的效率。TreeMap集合主要是对所有的key进行排序,从而保证所有的key-value映射关系处于有序状态,TreeMap集合再元素的添加、删除和定位映射性能较低
  • Coolections类可以对集合的元素进行排序、反序、去极值、循环移位、查询和修改的功能,还可以将集合对象设置不可变、对集合对象实现同步控制等方法

集合总结

各种线性表选择策略

1.数组:是以一段连续内存保存数据的;随机访问是最快的,但不支持插入、删除、迭代等操作

2.ArrayList与ArrayDeque:以数组实现;随机访问速度还行,插入、删除、迭代操作速度一般;线程不安全

3.Vector:以数组实现;随机访问速度一般,插入、删除、迭代速度不太好;线程安全

4.LinkedList:以链表实现;随机访问速度不太好,插入、删除、迭代速度非常快
访问效率最高的是ArrayList,HashTable次之

如果你会进行大量的插入/删除操作,而不是对容器中的元素进行简单的访问,那就该用LinkedList了

在单线程下:vector和hashtable已经被ArrayList和hashMap代替,所以效率是最低的,

1、如果线程要求安全,使用Vector,Hashtable

2、如果不要求线程安全,应使用ArrayList,LinkedList,HashMap

3、如果要求键值对,则使用HashMap、Hashtable

4、如果数据很大,又要线程安全考虑Vector

相关文章: