提示:本文介绍的集合类有很多,有的是日常开发常用的,有的是面试常问的,建议大家都了解一点。
一、容器的分类
Java 容器分为 Collection
和 Map
两大类,其下又有很多子类,如下所示:
这里有个面试点:Collection 和 Collections 有什么区别?
Collection 是一个集合接口
Collections 是一个包装类,包含了很多静态方法,不能被实例化,就像一个工具类,比如提供的排序方法:Collections. sort(list)。
二、List、Set、Map 之间的区别是什么
三、List
1、ArrayList 和 LinkedList 的区别是什么?
- 数据结构:
ArrayList
是动态数组的数据结构实现,而LinkedList
是双向链表的数据结构实现。 - 查询效率:
ArrayList
比LinkedList
在随机访问的时候效率要高,因为LinkedList
是线性的数据存储方式,所以需要移动指针从前往后依次查找。 - 增删效率:在非首尾的增加和删除操作,
LinkedList
要比ArrayList
效率要高,因为ArrayList
增删操作要影响数组内的其他数据的下标。
综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList
,而在插入和删除操作较多时,更推荐使用 LinkedList
。
2、ArrayList 和 Vector 的区别是什么?
- 线程安全:
Vector
使用了Synchronized
来实现线程同步,是线程安全的,而ArrayList
是非线程安全的。 - 性能:
ArrayList
在性能方面要优于Vector
,同样是因为Synchronized
,每个操作都需要去获取锁。 - 扩容:
ArrayList
和Vector
都会根据实际的需要动态的调整容量,只不过在Vector
扩容每次会增加 1 倍,而ArrayList
只会增加 50%。
不推荐使用Vector
,性能非常低。在需要保证线程安全的场景下,可以使用Collections.synchronizedList()
将 List
转为线程安全的 SynchronizedList
。或者使用写时复制的CopyOnWriteArrayList
四、Map
1、HashMap 的实现原理
HashMap
的数据结构是数组 + 链表 + 红黑树,通过put(key,value)
存储,get(key)
来获取。在存储时,对key进行哈希计算得到哈希值,确定在数组中的位置,如果没有哈希冲突,直接可以存储元素。如果产生哈希冲突,会遍历链表,判断哈希值和key值,决定是修改还是插入链表末尾。
链表在默认配置下,超过8位会转成红黑树,增加效率。
HashMap扩容时会先把数组大小扩容为原数组的两倍,再对原数组的元素重新确定位置,转移到新数组中。
想要了解更详细的实现原理,源码等信息,请参考之前发布的《你真的懂HashMap吗???》一文
2、HashMap 和 Hashtable 有什么区别?
- 存储:
HashMap
的key 和 value 都可以为 null,而Hashtable
不允许。 - 线程安全:
Hashtable
使用了Synchronized
来实现线程同步,是线程安全的,而HashMap
是非线程安全的。
不推荐使用Hashtable
,性能非常低。在需要保证线程安全的场景下,可以使用ConcurrentHashMap
,在Java 1.8 优化后,性能非常客观。
3、HashMap 和 TreeMap有什么区别?
- 数据结构:
HashMap
的数据结构是 数组+链表+红黑树,TreeMap
的数据结构是红黑树。 - 实现接口:
TreeMap
和HashMap
都继承自AbstractMap
,但是需要注意的是TreeMap
它还实现了NavigableMap
接口和SortedMap
接口,拥有对集合内元素的搜索能力和根据键key的排序能力。 - 性能:
HashMap
适用于在Map中插入、删除和定位元素,Treemap
适用于按自然顺序或自定义顺序遍历键(key)。
五、Iterator
1、Iterator 是什么?
Iterator
接口提供遍历任何 Collection
的接口。我们可以从一个 Collection
中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration
,迭代器允许调用者在迭代过程中移除元素。
2、Iterator 和 ListIterator 有什么区别?
-
Iterator
可以遍历Set
和List
集合,而ListIterator
只能遍历List
。 -
Iterator
只能单向遍历,而ListIterator
可以双向遍历(向前/后遍历)。 -
ListIterator
继承Iterator
接口,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。
3、Iterator 怎么使用?有什么特点?
List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.println(s);
}
Iterator
的使用非常简单,通过集合的iterator()
获取实例,根据hasNext()
遍历元素。Iterator
的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException
异常。文章来源:https://www.toymoban.com/news/detail-491641.html
总结
Java中的容器在日常开发中使用频率非常高,根据不同的业务需求选择不同的容器非常重要,不仅可以提高性能,也能减少出错。但这需要对每个容器都有相对深入的理解。
希望我的分享能对你理解Java中的容器有所帮助。文章来源地址https://www.toymoban.com/news/detail-491641.html
到了这里,关于一文搞懂Java中的容器(集合类)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!