目录

1.什么是Java集合类?

1.1 什么是Java集合API?

1.2 什么是Iterator?

2.集合和数组的区别

3.Collection集合的方法

4.常用集合的分类(总结)

4.1 List和Set集合详解

4.2 Map详解

由于近期面试都或多或少提到了集合类,可见其重要性和实用性,于是结合以前的知识,参考了一些博客和贴吧论坛,整理了以下笔记并且优化了以下排版,有一些简单易懂的图片也借鉴了一下,主要讲解的是各个具体实现类的特性,结构优缺点等等。本文用于学习交流,若有不足之处,请指正。


1.什么是Java集合类?

集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。

框架图:

 

1.1 什么是Java集合API?

  Java集合框架API是用来表示和操作集合的统一框架,它包含接口、实现类、以及帮助程序员完成一些编程的算法。简言之,API在上层完成以下几件事:

  ● 编程更加省力,提高城程序速度和代码质量

  ● 非关联的API提高互操作性

  ● 节省学习使用新API成本

  ● 节省设计新API的时间

  ● 鼓励、促进软件重用

        具体来说,有6个集合接口,最基本的是Collection接口,由三个接口Set、List、SortedSet继承,另外两个接口是Map、SortedMap,这两个接口不继承Collection,表示映射而不是真正的集合。

1.2 什么是Iterator?

  一些集合类提供了内容遍历的功能,通过java.util.Iterator接口。这些接口允许遍历对象的集合。依次操作每个元素对象。当使用 Iterators时,在获得Iterator的时候包含一个集合快照。通常在遍历一个Iterator的时候不建议修改集合本省。

  • Iterator:只能正向遍历集合,适用于获取移除元素。
  • ListIerator:继承Iterator,可以双向列表的遍历,同样支持元素的修改。

2.集合和数组的区别

è¿éåå¾çæè¿°

3.Collection集合的方法

è¿éåå¾çæè¿°

4.常用集合的分类(总结)

Java集合框架主要包括两种类型的容器,一种是集合(Collection),另一种是图(Map)。

Collection 接口的接口 对象的集合(单列集合) 
├——-List 接口:元素按进入先后有序保存,可重复 
│—————-├ LinkedList 接口实现类, 底层数据结构是链表, 插入删除, 没有同步, 线程不安全 
│—————-├ ArrayList 接口实现类, 底层数据结构是数组, 随机访问, 没有同步, 线程不安全 
│—————-└ Vector 接口实现类 底层数据结构是数组, 同步, 线程安全 
│ ———————-└ Stack 是Vector类的实现类 
└——-Set 接口: 仅接收一次,不可重复,并做内部排序 
├—————-└HashSet 使用底层使用hash表(数组)存储元素 (无序)
│————————└ LinkedHashSet 链表维护元素的插入次序 (FIFO,由链表保证元素有序,哈希表保证元素唯一)
└ —————-TreeSet 底层实现为二叉树(红黑树),元素排好序(根据比较的返回值是否是0来决定元素是否唯一)

Map 接口 键值对的集合 (双列集合) 
├———Hashtable 接口实现类, 同步, 线程安全 
├———HashMap 接口实现类 ,没有同步, 线程不安全- 
│—————–├ LinkedHashMap 双向链表和哈希表实现 
│—————–└ WeakHashMap 
├ ——–TreeMap 红黑树对所有的key进行排序 (有序)
└———IdentifyHashMap

注意:Hashtable不允许null值,HashMap允许null值(key和value都允许)

4.1 List和Set集合详解

4.1.1 list和set的区别

è¿éåå¾çæè¿°

4.1.2 List
(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素 
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素 
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素 

è¿éåå¾çæè¿°

  • ArrayList与LinkedList的区别和适用场景

Arraylist: 
优点:ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高(在内存里是连着放的)。 
缺点:因为地址连续, ArrayList要移动数据,所以插入和删除操作效率比较低。

LinkedList: 
优点:LinkedList基于链表的数据结构,地址是任意的,所以在开辟内存空间的时候不需要等一个连续的地址,对于新增和删除操作add和remove,LinedList比较占优势。LinkedList 适用于要头尾操作或插入指定位置的场景 
缺点:因为LinkedList要移动指针,所以查询操作性能比较低。 

4.1.3 set

  1. HashSet:底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,但只能放入一个null,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
  2. LinkedHashSet:底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。 
  3. TreeSet:底层数据结构采用二叉树来实现,元素唯一且已经排好序,不允许放入null值 ;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法; 
  4. 适用场景分析:HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。为快速查找而设计的Set,我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。 

4.2 Map详解

Map用于保存具有映射关系的数据,Map里保存着两组数据:key和value,它们都可以使任何引用类型的数据,但key不能重复。所以通过指定的key就可以取出对应的value。而HashMap是用哈希算法实现Map的具体实现类,别搞混了。

1 HashMap

  • HashMap是基于哈希表的Map接口的非同步实现,继承自AbstractMap,AbstractMap是部分实现Map接口的抽象类。在平时的开发中,HashMap的使用还是比较多的。我们知道ArrayList主要是用数组来存储元素的,LinkedList是用链表来存储的,那么HashMap的实现原理是什么呢?先看下面这张图:
  • 在之前的版本中,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当链表中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
  • HashMap数据结构图:

  • 在HashMap中要找到某个元素,需要根据key的hash值来求得对应数组中的位置。对于任意给定的对象,只要它的hashCode()返回值相同,那么程序调用hash(int h)方法所计算得到的hash码值总是相同的。我们首先想到的就是把hash值对数组长度取模运算,这样一来,元素的分布相对来说是比较均匀的。但是,“模”运算的消耗还是比较大的,在HashMap中,(n – 1) & hash用于计算对象应该保存在table数组的哪个索引处。HashMap底层数组的长度总是2的n次方,当数组长度为2的n次幂的时候,(n – 1) & hash 算得的index相同的几率较小,数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。

  • 关于HashMap有一篇博客讲的很细,可以去参考:https://angela.blog.csdn.net/article/details/104889549#comments

2.LinkedHashMap

LinkedHashMap继承自HashMap,它主要是用链表实现来扩展HashMap类,HashMap中条目是没有顺序的,但是在LinkedHashMap中元素既可以按照它们插入图的顺序排序,也可以按它们最后一次被访问的顺序排序。

3.TreeMap

TreeMap基于红黑树数据结构的实现,键值可以使用Comparable或Comparator接口来排序。TreeMap继承自AbstractMap,同时实现了接口NavigableMap,而接口NavigableMap则继承自SortedMap。SortedMap是Map的子接口,使用它可以确保图中的条目是排好序的。

在实际使用中,如果更新图时不需要保持图中元素的顺序,就使用HashMap,如果需要保持图中元素的插入顺序或者访问顺序,就使用LinkedHashMap,如果需要使图按照键值排序,就使用TreeMap。
 

HashMap和HashTable的比较: 

è¿éåå¾çæè¿°

小结: 

  1. HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap允许空键值,而HashTable不允许。
  2. HashMap:适用于Map中插入、删除和定位元素。 
  3. Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
  4. LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的; 
  5. HashMap,TreeMap是非线程安全的,HashTable是线程安全的; 
  6. StringBuilder是非线程安全的,StringBuffer是线程安全的。
  7. HashMap可以通过Map m = Collections.synchronizedMap(hashMap)来达到同步的效果。

 

本文参考了以下博客:

 

版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: