Java基础总结(二)
Java集合
集合是干什么用的?
集合是用于存储数据的容器。任何的集合都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
集合的特点:用于存储对象;集合长度可变。
同样是存储数据,集合和数组有什么不同?
- 数组是固定长度;集合可变长度。
- 数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
- 数组存储的元素必须是同一个数据类型;集合存储的对象可以使不同数据类型。
使用集合的好处:
- 容量自增长。
- 提供高性能的数据结构和算法。
- 允许不同API之间的互操作,API之间可以来回传递集合。
- 提高代码复用性和可操作性。
- 通过使用JDK自带的集合类,可以降低代码维护和学习新API成本。
Iterator接口:用于遍历集合元素的接口。
该接口中定义了三个方法:
- 调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
- 调用 it.hasNext() 用于检测集合中是否还有元素。
- 调用 it.remove() 将迭代器返回的元素删除。
Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
- Collection接口:一次存一个元素,是单列集合。
- Map接口:一次存一对元素,是双列集合。键值对。
Collection集合主要有List和Set两大接口
List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引,元素可以重复。
Set:无序(存入和取出顺序有可能不一致),不可以存储重复元素,必须保证元素唯一性。


List集合的主要实现类:ArrayList,LinkedList,Vector。
ArrayList,LinkedList,Vector的比较
|
|
ArrayList |
LinkedList |
Vector |
|
底层实现 |
数组 |
双向链表 |
数组 |
|
同步性及效率 |
不同步,非线程安全,效率高,支持随机访问 |
不同步,非线程安全,效率高 |
同步,线程安全,效率低 |
|
特点 |
查询快,增删慢 |
查询慢,增删快 |
查询快,增删慢 |
|
默认容量 |
10 |
/ |
10 |
|
扩容机制 |
1.5倍 |
/ |
2倍 |
总结:ArrayList和Vector基于数组实现,对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
Set集合的主要实现类:HashSet,TreeSet。
HashSet,TreeSet,LinkedHashSet的区别:
|
|
HashSet |
TreeSet |
LinkedHashSet |
|
底层实现 |
HashMap |
红黑树 |
LinkedHashMap |
|
重复性 |
不允许重复 |
不允许重复 |
不允许重复 |
|
有无序 |
无序 |
有序,支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式 |
有序,以元素插入的顺序来维护集合的链接表 |
|
时间复杂度 |
add(),remove(),contains()方法的时间复杂度是O(1) |
add(),remove(),contains()方法的时间复杂度是O(logn) |
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet,时间复杂度是O(1)。 |
|
同步性 |
不同步,线程不安全 |
不同步,线程不安全 |
不同步,线程不安全 |
|
null值 |
允许null值 |
不支持null值,会抛异常 |
允许null值 |
|
比较 |
equals() |
compareTo() |
equals() |
Map接口
Map是一种把键对象和值对象映射的集合,它的每一个元素都包含一堆键对象和值对象。从Map集合中检索元素时,只要能给出键对象,就会返回对应的值对象。

Map的常用实现类:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap
HashMap、HashTable、TreeMap的区别:
TreeMap:基于红黑树实现。
HashMap:基于哈希表实现。
HashTable:和HashMap类似,但它是线程安全的。它是遗留类,不应该去使用了,现在可以使用ConcurrentHashMap来支持线程安全,并且效率会更高,因为ConcurrentHashMap引入了分段锁。
集合工具类Collections,提供一系列静态方法,方便对集合的操作,实现对集合的查找、排序、替换、线程安全化等操作。
数据工具类Arrays,用于操作数组对象的工具类,里面都是静态方法。
如何选用集合?
主要根据集合的特点来选用,比如我们需要根据键值获取到元素值时就选用Map接口下的集合,需要排序时选择TreeMap,不需要排序时就选择HashMap,需要保证线程安全就选用ConcurrentHashMap。当我们只需要存放元素值时,就选择Collection接口的集合,需要保证元素唯一时选择实现Set接口的集合,比如TreeSet或HashSet;不需要就选择实现List接口的,比如ArrayList或LinkedList,然后再根据实现这些接口的集合的特点来选用。
说说List,Set,Map三者的区别?
List(对付顺序的好方法):存储的元素是有序的,可重复的。
Set(注重独一无二的性质):存储的元素是无序的,不可重复的。
Map(用Key来搜索的专家):使用键值对(key-value)存储,key是无序的,不可重复的,value是无序的,可重复的。每个键最多映射到一个值,key相当于函数关系y=f(x)中的x,value代表y。
集合框架底层数据结构总结
List
- Arraylist:Object[] 数组
- Vector:Object[] 数组
- LinkedList:双向链表
Set
- HashSet(无序,唯一):基于HashMap实现的,底层采用HashMap来保存元素。
- LinkedHashSet(有序,唯⼀) : LinkedHashSet 是 HashSet 的子类,并且其内部是通过LinkedHashMap 来实现的。
- TreeSet (有序,唯⼀): 红黑树(自平衡的排序⼆叉树)。
Map
- HashMap : JDK1.8 之前 HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。
- LinkedHashMap : LinkedHashMap 继承⾃ HashMap ,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了⼀条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
- Hashtable : 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的。
- TreeMap : 红黑树(自平衡的排序⼆叉树)。
Set和List的区别
1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
以下情况使用 ArrayList :
- 频繁访问列表中的某一个元素。
- 只需要在列表末尾进行添加和删除元素操作。
- 以下情况使用 LinkedList :
- 你需要通过循环迭代来访问列表中的某些元素。
- 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

浙公网安备 33010602011771号