Java集合容器概述

本文详细介绍了Java集合框架中的List、Set、Map的区别,包括它们的实现方式、顺序、性能和线程安全性。特别关注了ArrayList、LinkedList、HashSet、TreeSet、HashMap、Hashtable和ConcurrentHashMap的特性和使用场景。
摘要由CSDN通过智能技术生成

集合的特点:1、对象封装数据,对象多了也需要存储,集合用于存储对象。2、对象的个数确定用数组,不确定则用集合。

集合与数组的区别

1、数组定长,集合不定长;

2、数组可以存基本数据类型,也可以存储引用类型,集合只能存储引用类型数据;

3、数组的数据必须是同一种类型,集合中的数据可以是不同的数据类型。

说说 List,Set,Map 三者的区别?三者底层的数据结构?

答:首先,Java中有Map和Collection两大容器,Collection有set、List、Queue作为子接口,所以Java中常用的三大接口。

List是指有序的可重复集合,典型的实现有ArrayList和LinckedList;其中ArrayList基于动态数组实现,LinckedList基于双向链表。查找元素效率高,但增加删除效率低(因为可能会引起元素位置改变,要维护顺序)。

Set是一个不允许有重复元素的无序集合,hashSet,TreeSet是典型的实现;hashset是基于hashmap实现的,TreeSet是基于红黑树实现。查找元素效率低,但增加删除元素效率高。

Map是键值对集合,其中键是唯一的,常见的实现有hashmap和treemap;hashmap基于散列实现,而treemap基于红黑树。

比较 HashSet、LinkedHashSet 和 TreeSet 三者的异同

实现数据结构:hashmap、双向链表、红黑树

顺序:没有明确顺序,适合快速查找、按插入顺序、按树的比较顺序

性能:O(1)、近似于O(1)、O(logn)

空间:消耗最小、要维护双向链表的顺序,消耗较大、树结构消耗更大

有哪些集合是线程不安全的?怎么解决呢?

答:安全的有vector、stack、hashtable和枚举类型。

不安全的有:ArrayList   LinkedList   HashMap   HashSet    TreeSet   TreeMap、ConcurrentHashMap等 这些集合在多线程环境中进行修改时可能会导致意外行为。

可以通过以下几种策略解决:

使用线程安全版本的集合如vector和stack等;使用Collections.synchronizedXXX() 方法转换成线程安全的集合;使用读写锁;写时复制。

HashMap 和 Hashtable 的区别?HashMap 和 HashSet 区别?HashMap 和 TreeMap 区别?

同步性

性能:线程安全性能肯定低一些;Map和Tree分别是O(1)、O(logn)

实现方式

顺序

null键和null值:hashmap允许一个null键和多个null值,hashset中允许有一个nll值,hashtable不允许。

为什么hashmap线程不安全而hashtable线程安全?

答:主要是因为它的所有公共方法都被synchronized关键字修饰了,意味着在多线程环境中,同时间内只会有一个实例对象能访问hashtable的实例,hashmap不是性能安全的,因为他没有任何同步它的方法。

ArrayList LinkedList 的区别是什么?

实现方式、同步性、删除修改的性能、空间消耗。

hashSet的实现原理是什么?如何检查重复,如何保证数据不可重复?

答:hashset基于hashmap实现,因为hashmap的键是唯一的,所以hashset的值存放在键中,这样就保证了hashset中的元素不重复。hashset在存放数据的时候需要对hashcode和equals都进行比较,如果在hashcode中找到了重复的元素就比较equals,两者都一样就认定这个元素重复不存储,否则重新散列存储。

hashMap的底层原理是什么?

答:基于哈希表的map接口实现的,它允许null作为键和值。选用数组和链表的数据结构来实现。当尝试存储一个键值对时(put方法),首先要计算键的hashcode,一般是对数组的长度取模来实现,以决定存储的位置,如果该位置为空,放入新元素;如果两个以上的键hashcode映射到同一个位置时,认为发生了哈希冲突,采用链表来解决,即使用链表插入到重复元素的后面。

每次put的时候都会进行扩容检查,即查看当前hashmap的大小是否超过了其阈值(数组大小*负载因子,默认为0.75),如果超过了,就将数组翻倍,并重新分配数据。

hashmap是线程不安全的,在多线程情况下修改数据可能会发生意外。

HashMap是如何实现扩容的?它的长度为什么是 2 的幂次方?

答:如果hashmap的大小超过了阈值(数组长度*负载因子)就需要扩容,首先确定新的数组大小,并新建数组,一般是原数组的2倍,旧数组里的数据都要重新进行哈希,如果新位置为空,直接放置,如果重复,用链表插入在后面。

数组长度是2 的幂次方:

1、优化索引计算,使用2的幂次方时,能够使用哈希值和其容量-1快速得出索引位置,这比取模运算更快。避免选择质数作为容量,提升索引性能。

2、方便扩容,新的容量简单地是原来的2倍,使得数据迁移相对简单。

是为了实现高效快速的索引,同时也为了方便实现扩容。

ConcurrentHashMap Hashtable 的区别?
答:两者都是线程安全的,只是在加锁机制上有所差别。
锁和性能:Hashtable为了保证同步性,用一个全局锁来同步整个哈希表,这意味着每次只有一个线程可以访问表的任何部分,限制了并发性; concurrenthashmap是对数组进行分段加锁,分成几个段,每个段都有独立的锁;多个线程可以同时访问哈希表的不同部分,提升了访问性能。
null键和值:hashtable不允许有null键或值;concurrenthashmap不允许null键,但可以有null值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值