Java复习01 集合
在Java中,集合(Collections)是一种用来存储一组对象的结构。想象一下有一个装东西的箱子,这个箱子可以装很多不同类型的东西,例如书、DVD或者玩具。Java的集合也是这样,但是它专门用来装载对象(比如字符串、整数等等)。
现在,让我们区分Collection
和Map
,以及Collection
里的List
和Set
。
1. Collection 和 Map 的区别
- Collection: 这是一个单列集合,它的意思是每一个元素只包含一个对象(就像一串单独的珍珠),例如一个珍珠串。在
Collection
接口下面有不同类型的集合,比如List
和Set
。 - Map: 这是一种双列集合,意思是它存储的每个元素包含两部分:一个键(Key)和一个值(Value),就像是一个词典。在词典中,每个单词(键)都对应一个定义(值)。在Java的
Map
中,你可以通过键来快速找到对应的值。
2. Collection 里面 List 和 Set 的区别
这两者都是Collection
的子接口,但是它们存储元素的方式有所不同:
- List: 想象一下你有一个购物清单,你可以按照顺序在上面写下你要买的东西,就像牛奶、面包、牛奶。注意,你可以写下多次牛奶。这表明
List
是有序的,并且可以包含重复的元素。在Java的List
中,每个元素都有一个特定的位置,就像购物清单上的物品。 - Set: 现在假设你是一个集邮爱好者,你的集邮册里面不会想有重复的邮票,每一枚邮票都是独一无二的。这个集邮册就像是Java中的
Set
,它不允许重复的元素,也不保证元素的顺序。所以,如果你尝试把相同的邮票加入集邮册,它就会拒绝这个重复的。
3. List 里面 ArrayList 和 LinkedList 的区别
ArrayList
和LinkedList
都是Java中List
接口的两种不同实现。我们可以用一个比喻来解释它们之间的区别:
想象一下你有一排学生坐在教室里,他们是按照座位号顺序排列的。这就像一个ArrayList
,每个学生都有一个固定的座位号(也就是在列表中的索引位置),你可以很快地找到任何一个学生(元素)只要知道他们的座位号。ArrayList
在内部使用一个数组来存储元素,因此访问任何元素都非常快,就像直接叫一个学生的座位号一样简单。
现在想象一下,有一列孩子站成一排等着上滑梯。每个孩子只知道前一个和后一个孩子是谁。如果你想找到队列中的某个特定孩子,你需要从头或者从尾开始,一个接一个地问直到找到那个孩子。这个队列就像是一个LinkedList
,每个元素都保持着与前一个和后一个元素的连接,但是它们并不知道自己在队列中的具体位置。LinkedList
在内部使用双向链表来存储元素,因此插入和删除元素非常快,因为这就像是让一个孩子加入或离开滑梯队列一样简单。
总结一下ArrayList
和LinkedList
的主要区别:
- ArrayList:
- 优点: 快速随机访问性能(快速定位元素)。
- 缺点: 在列表中间插入和删除元素可能很慢,因为这可能涉及到移动元素来填补空白或者创建空间。
- 适用场景: 当你需要频繁地通过索引访问元素,而且添加或删除操作主要发生在列表的末尾时。
- LinkedList:
- 优点: 插入和删除元素通常更快,尤其是在列表中间。
- 缺点: 随机访问性能较慢(查找元素需要时间)。
- 适用场景: 当你需要频繁地在列表中间进行添加或删除操作时。
4. Map 里面 HashMap()
假设我们有一个巨大的储物柜(HashMap
),而每个储物格可以放你的东西,比如运动鞋。
每个储物格都有一个号码,但是这个号码不是随便给的,它是通过你鞋子的某个特别标记计算出来的。这个过程就像一个数学魔法,可以把鞋子的标记转化成储物格的号码。所以当你需要存储一双鞋时,你就使用这个魔法计算出储物格号码,然后把鞋子放进去。
现在,当你下次来,想要取回你的鞋子,你不需要去每个储物格门口找,你只需要记住那个特别标记,再用同样的魔法计算一次,就能直接知道你的鞋子在哪个储物格了。这样你就可以很快地取到你的鞋子。
但是,有时候会出现一个问题。可能会有两双不同的鞋,它们的特别标记通过魔法计算出来的储物格号码是一样的。这就像两个不同的学生被分配到了同一个宿舍。HashMap
的解决办法是在同一个储物格里面加个小盒子,这样每双鞋都有自己的小盒子。虽然这样找鞋子可能会慢一点,因为你需要检查每个小盒子,但通常来说,这个魔法计算得很好,所以每个储物格里只有一两个小盒子,你还是很快就能找到你的鞋子。
HashMap
就像这个巨大的储物柜,帮你快速地存储和取出东西。每次你想存东西,它都会帮你找到一个地方放。而每次你想取东西时,只要你知道那个特别的标记,你就能迅速找到它们。这就是HashMap
的魔法!
4.1 HashMap的可能问题
- 基本概念: 他们可能会问你什么是
HashMap
?- “HashMap是Java中的一个集合类,它可以存储键值对,并且可以快速地通过键来访问值。它是基于哈希表实现的,所以它的获取和插入的速度很快,因为它通过哈希函数直接定位到它的值的存储位置。”
- 内部工作原理: 他们可能会询问
HashMap
是如何工作的 ?- “HashMap通过哈希函数来计算键的哈希码,哈希码决定了键值对在内部数组中的存储位置。如果有两个不同的键产生了相同的哈希码,并且哈希函数将它们定位到了相同的位置,这种情况称为哈希冲突。HashMap通过链表或红黑树来解决冲突,这意味着每个位置实际上可以存储多个键值对。”
- 性能问题: 面试官可能会问到性能,比如
HashMap
的时间复杂度 ?- “HashMap的
get
和put
操作通常有常数时间的性能,即O(1),但这依赖于哈希函数的质量和键值对的分布。如果发生了很多哈希冲突,性能可能会退化至O(n),其中n是哈希桶中元素的数量。”
- “HashMap的
- 容量和负载因子: 关于
HashMap
的初始化容量和负载因子 ?- “HashMap有一个初始容量值,它是存储元素的内部数组的大小,还有一个负载因子,用来衡量HashMap在自动增加其容量(重新哈希)之前可以有多满。默认的负载因子是0.75,这是一个在时间和空间成本之间的折衷。”
- 线程安全: 如果问到线程安全 ?
- “HashMap本身不是线程安全的,如果在多线程环境中使用HashMap,需要额外的同步措施。或者,可以使用ConcurrentHashMap,它是专为多线程环境设计的。
- 和其他Map的比较: 也许会让你跟其他
Map
实现比较,比如Hashtable
或TreeMap
?- “与Hashtable比较,HashMap是非同步的,因此在单线程环境下速度更快,而Hashtable是线程安全的。与TreeMap比较,HashMap通常更快,因为TreeMap保持键的排序,其
get
和put
操作的时间复杂度为O(log n)。”
- “与Hashtable比较,HashMap是非同步的,因此在单线程环境下速度更快,而Hashtable是线程安全的。与TreeMap比较,HashMap通常更快,因为TreeMap保持键的排序,其
总结一下:
- Collection: 一组单一元素的集合,可以是有序的(
List
),也可以是唯一的(Set
)。 - Map: 一组成对的键值对集合,可以通过键来快速查找值。
- List: 一个可以包含重复元素并且有序的集合。
- Set: 一个不可以有重复元素,元素位置也不固定的集合。
在使用Java集合框架时,你可以根据需要存储的数据类型和数据操作来选择最合适的集合类型。