首页 > 其他分享 >HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别

HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别

时间:2023-11-08 15:38:14浏览次数:44  
标签:Map ConcurrentHashMap HashMap HashSet TreeMap Hashtable public


一、HashMap和TreeMap区别

1、HashMap是基于散列表实现的,时间复杂度平均能达到O(1)。


    TreeMap基于红黑树(一种自平衡二叉查找树)实现的,时间复杂度平均能达到O(log n)。


2、HashMap、TreeMap都继承AbstractMap抽象类;TreeMap实现SortedMap接口,所以TreeMap是有序的!HashMap是无序的。

    接口层次:

    public interface SortedMap<K,V> extends Map<K,V>

    public interface NavigableMap<K,V> extends SortedMap<K,V>

    public class HashMap<K,V>     extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable

    public class HashMap<K,V>    extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable

    

3、两种常规Map性能

    HashMap:适用于在Map中插入、删除和定位元素。

    Treemap:适用于按自然顺序或自定义顺序遍历键(key)。    


4.总结:HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。



二、HashMap和Hashtable的区别

HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。


HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。

由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。

HashMap不能保证随着时间的推移Map中的元素次序是不变的。


我们能否让HashMap同步?

HashMap可以通过下面的语句进行同步:

Map m = Collections.synchronizeMap(hashMap);


Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。



三、HashSet和HashMap的区别

    HashSet是基于HashMap实现的。


1. public class HashSet<E> extends AbstractSet<E>  implements Set<E>, Cloneable, java.io.Serializable  
2. {  
3. static final long serialVersionUID = -5024744406713321676L;  
4.   
5. private transient HashMap<E,Object> map;  
6.   
7. private static final Object PRESENT = new Object();  
8.   
9. public HashSet() {  
10. new HashMap<>();  
11.     }  
12. public HashSet(Collection<? extends E> c) {  
13. new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));  
14.         addAll(c);  
15.     }  
16. public boolean add(E e) {  
17. return map.put(e, PRESENT)==null;  
18.     }  
19. public boolean remove(Object o) {  
20. return map.remove(o)==PRESENT;  
21.     }  
22.     .......  
23. }

    




HashMap

HashSet

HashMap实现了Map接口

HashSet实现了Set接口

HashMap储存键值对

HashSet仅仅存储对象

使用put()方法将元素放入map中

使用add()方法将元素放入set中

HashMap中使用键对象来计算hashcode值                                                                   

HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false

HashMap比较快,因为是使用唯一的键来获取对象

HashSet较HashMap


    


    


四、ConcurrentMap

不可以有null键,线程安全,原子操作。一个ConcurrentHashMap 由多个segment 组成,每个segment 包含一个Entity 的数组。这里比HashMap 多了一个segment 类。该类继承了ReentrantLock 类,所以本身是一个锁。当多线程对ConcurrentHashMap 操作时,不是完全锁住map, 而是锁住相应的segment 。这样提高了并发效率。缺点:当遍历ConcurrentMap中的元素时,需要获取所有的segment 的锁,使用遍历时慢。锁的增多,占用了系统的资源。使得对整个集合进行操作的一些方法





五、LinkedHashMap是HashMap的一个子类

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

      ConcurrentHashMap原理分析 



六、java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap.

标签:Map,ConcurrentHashMap,HashMap,HashSet,TreeMap,Hashtable,public
From: https://blog.51cto.com/u_809530/8255301

相关文章

  • HashMap---jdk8
    概述HashtablebasedimplementationoftheMapinterface.Thisimplementationprovidesalloftheoptionalmapoperations,andpermits<tt>null</tt>valuesandthe<tt>null</tt>key.(The<tt>HashMap</tt>classis......
  • hashmap的小应用---投票去旅游
    在学习了map之后,使用简单的hashmap进行简单的全班同学投票旅游地点packagecom.itheima.myMap;importjava.util.*;importjava.util.function.BiConsumer;publicclassText2{publicstaticvoidmain(String[]args){//模拟投票Randomra=newRandom......
  • LinkedHashMap
    概述Hashtableandlinkedlistimplementationofthe<tt>Map</tt>interface,withpredictableiterationorder.Thisimplementationdiffersfrom<tt>HashMap</tt>inthatitmaintainsadoubly-linkedlistrunningthroughallofitsen......
  • 小测试:HashSet可以插入重复的元素吗?
    Set的定义是一群不重复的元素的集合容器。也就是说,只要使用Set组件,应该是要保证相同的数据只能写入一份,要么报错,要么忽略。当然一般是直接忽略。如题,HashSet是Set的一种实现,自然也符合其基本的定义。它的自然表现是,一直往里面插入数据,然后最后可以得到全部不重复的数据集......
  • HashMap源码详解
    HashMap简介HashMap是Java语言中的一种集合类,它实现了Map接口,用于存储Key-Value对。它基于哈希表数据结构,通过计算Key的哈希值来快速定位Value的位置,从而实现高效的插入、删除和查找操作。下面我们对照着JAVA1.8中的HashMap源码来分析一下它的内部实现逻辑基本的结构在开始分析......
  • HashMap的长度是2的幂次方
    为了能让HashMap存取高效,尽量减少碰撞,也就是要尽量把数据分配均匀。Hash值的范围值-2147483648到2147483647,前后加起来大概40亿的映射长度,只要哈希函数映射的比较均匀松散,一般应用是很难出现碰撞的。但问题是一个40亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。......
  • 面试高频题:你如何知道HashMap正在进行扩容操作?
    亲爱的小伙伴们,大家好!我是小米,一个热爱技术分享的小编。今天,我们将一起来探讨一个程序员们在日常工作中常常遇到的问题——如何知道HashMap正在扩容。HashMap,作为Java中最常用的数据结构之一,经常在我们的代码中扮演着关键的角色。了解HashMap的工作原理,特别是它的扩容机制,可以帮助......
  • 如何用Java实现一个线程安全的HashMap?
    有以下几种方式可以实现线程安全的HashMap:使用ConcurrentHashMap类实现:ConcurrentHashMap是Java集合框架中的一个类,它是线程安全的HashMap实现。ConcurrentHashMap的实现方式是将一个大的Map拆分成多个小的Map片段,每个Map片段上都有自己的锁,这样多个线程在访问不同的Map片段时就可......
  • HashMap集合遍历随机性问题分析
    一、原因分析1.1HashMap对象的遍历HashMap的遍历是通过此类中字段table数组进行顺序遍历,原因如下所示:1#HashMap迭代遍历源码2publicfinalbooleanhasNext(){3returnnext!=null;4}56finalNode<K,V>nextNode(){7Node<K,V>[]t;......
  • 用HashMap创建jString,ArrayList的键值对用entrySet遍历
    用HashMap创建jString,ArrayList的键值对用entrySet遍历package随机点名器;importjava.util.*;publicclassTest1{publicstaticvoidmain(String[]args){HashMap<String,ArrayList<String>>m=newHashMap<>();ArrayList<String>......