1. 常见的Java集合类有哪些?
Java中常见的集合类主要分为两大类:Collection接口的实现类和Map接口的实现类。
-
Collection接口的主要实现类:
- List:ArrayList, LinkedList, Vector
- Set:HashSet, LinkedHashSet, TreeSet
- Queue:ArrayDeque, LinkedList, PriorityQueue
-
Map接口的主要实现类:
- HashMap 和 LinkedHashMap
- TreeMap
- Hashtable 和 Properties
2. ArrayList和LinkedList的区别是什么?
- 内部实现:ArrayList基于动态数组实现,支持随机访问;LinkedList基于双向链表实现,适合频繁插入和删除操作。
- 性能:ArrayList在随机访问效率高,但插入和删除操作涉及数组元素的移动,性能较低;LinkedList插入和删除操作效率高,但访问任意元素需要遍历链表。
- 空间占用:ArrayList会预分配一定容量的数组,可能会浪费内存;LinkedList每个元素都有额外的链表节点开销。
3. HashMap和Hashtable的区别是什么?
- 线程安全性:HashMap非线程安全,Hashtable是线程安全的(所有方法都使用synchronized关键字)。
- 空键和空值:HashMap允许键和值都为null;Hashtable不允许null键和null值。
- 性能:HashMap的性能通常优于Hashtable,因为后者的所有方法都是同步的,而HashMap的非同步设计有助于提高并发性能。
4. TreeMap和TreeSet的特点及用途?
- 排序:TreeMap和TreeSet基于红黑树实现,可以对元素进行排序(自然顺序或指定比较器)。
- 唯一性:TreeSet存储唯一元素,TreeMap存储键值对,并保持键的唯一性。
- 应用:适用于需要排序和唯一性约束的场景,例如需要按键或值排序的情况。
5. ConcurrentHashMap的特点和使用场景?
- 线程安全性:ConcurrentHashMap是线程安全的哈希表,使用了锁分段技术(Segment)或CAS操作保证并发访问的安全性。
- 性能:相比Hashtable和同步的HashMap,ConcurrentHashMap在高并发场景下具有更好的性能表现。
- 应用场景:适合需要高效并发访问的场景,如并发缓存、多线程环境下的数据管理等。
6. ConcurrentHashMap的实现原理是什么?为什么它比Hashtable性能更好?
- 实现原理:ConcurrentHashMap使用了分段锁(Segment)或CAS操作来支持并发访问。每个Segment维护一个HashEntry数组,每个数组元素是一个链表,通过哈希算法和位运算来确定元素存储位置,并使用synchronized或CAS来确保并发安全。
- 性能优势:相比Hashtable的全局锁机制,ConcurrentHashMap的分段锁技术使得不同Segment的操作可以并行进行,减少了线程竞争,提高了并发性能。
7. 如何实现一个线程安全的集合类?
- 可以使用Java提供的并发集合类,如ConcurrentHashMap、ConcurrentSkipListMap、CopyOnWriteArrayList等,它们已经针对并发环境进行了优化。
- 也可以通过使用同步集合类并手动在方法级别添加synchronized关键字来实现线程安全,不过这种方式可能会牺牲一定的性能。
- 使用锁机制(如ReentrantLock、ReadWriteLock)来保护共享数据访问。
8. ArrayList和Vector的区别是什么?它们在什么情况下分别使用?
- 区别:Vector是线程安全的动态数组实现,所有方法都使用了synchronized关键字来保证线程安全;ArrayList是非线程安全的动态数组实现。
- 使用场景:当需要线程安全时,可以使用Vector;而在单线程或者可以保证线程安全的情况下,推荐使用ArrayList,因为它不带同步开销,性能可能更好。
9. HashMap在扩容时会发生什么?如何影响性能?
- 扩容过程:当HashMap的元素数量超过负载因子(默认为0.75)乘以容量时,HashMap会进行扩容操作。扩容会重新计算每个元素的位置,并重新分配存储空间。
- 性能影响:扩容涉及重新计算哈希值、重新分配内存和重新插入元素,如果发生频繁扩容,可能会导致性能下降。因此,合理设置初始容量和负载因子是优化HashMap性能的重要因素。
10. Java中如何实现一个自定义的不可变集合类?
- 可以通过在构造函数中初始化所有数据,并将所有属性设置为final来保证不可变性。
- 对于集合类,可以使用Collections.unmodifiableXXX()方法将可变集合包装为不可变视图。
- 注意,不可变集合类应该确保所有内部数据在初始化后不可修改,以保证线程安全和可靠性。
221

被折叠的 条评论
为什么被折叠?



