1)常见的集合有哪些
-
Collection接口的子接口包括:Set接口(唯一)和List接口(有序)
-
Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
-
Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
-
List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
HashMap和HashTable以及ConcurrentHashMap的区别:
Hashtable
数组+链表实现,key,value都不能为null,线程安全,实现方式是修改数据时锁住整个HashTable,效率低。
初始大小11,扩容*2+1。HashMap
数组+链表实现,key,value都可以为null,线程不安全。
初始大小16,扩容*2。TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。效率不如HashMap,Map需要有序的场合才使用TreeMap。
ConcurrentHashMap
分段数组+链表实现,线程安全。用分离锁实现,允许多个修改操作并发。跨段修改时按顺序锁定所有段,再按顺序释放。
Properties 继承于 Hashtable ,来表示一个持久的属性集。一个唯一和IO流相结合的集合。
基本的存储方法 :setProperty(String key, String value)
getProperty(String key)
与流相关的方法
Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
- void store(OutputStream out, String comments)
- void store(Writer writer, String comments)
HashMap线程不安全
因为多线程环境下,使用Hashmap进行put操作可能会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。例如如下代码:
final HashMap<String, String> map = new HashMap<String, String>(2);
for (int i = 0; i < 10000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
map.put(UUID.randomUUID().toString(), "");
}
}).start();
}
Hashtable线程安全但效率低下
Hashtable容器使用synchronized来保证线程安全,但在线程竞争激烈的情况下Hashtable的效率非常低下。因为当一个线程访问Hashtable的同步方法时,其他线程访问Hashtable的同步方法时,可能会进入阻塞或轮询状态。如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且也不能使用get方法来获取元素,所以竞争越激烈效率越低。
分段锁
HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术
HashMap为什么要重写hashCode()和equals()方法
hashMap中,如果key为自定义类,那么就必须要重写hashCode()和equals()方法
在put方法中,判断key是否相等,用的是equals方法。其实get方法中也是一样。那么默认的equals方法就不一定能满足我们的要求了。因此要重写equals方法。
涉及到Object.hashCode()的通用约定了:
- 每次应用执行期间,在对象做equals比较所用到的信息没有修改之前,hashcode方法的返回值应该是相同的。
- 两个对象equals方法相同,那么hashCode值必须相同;
- 两个对象equals方法不同,那么hashCode值不一定不同。
如果只重写equals方法,不重写hashCode方法,那么显然会违反第二条约定
HashSet,TreeSet和LinkedHashSet的区别
总体而言,如果你需要一个访问快速的Set,你应该使用HashSet;当你需要一个排序的Set,你应该使用TreeSet;当你需要记录下插入时的顺序时,你应该使用LinedHashSet。
Set接口:线程都不安全
**1.**Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
2.Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象。
|——SortedSet接口——TreeSet实现类
Set接口——|——HashSet实现类
|——LinkedHashSet实现类
HashSet:
1.不能保证元素的排列顺序,顺序有可能发生变化
-
不是同步的 内部的数据结构是哈希表,是线程不安全的。
-
集合元素可以是null,但只能放入一个null
HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等
TreeSet:(TreeSet是二叉树实现的)
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式ÿ