Java中HashMap和Hashtable及HashSet的区别

Hashtable类  
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。

添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数。

Hashtable通过initial   capacity和load   factor两个参数调整性能。通常缺省的load   factor   0.75较好地实现了时间和空间的均衡。增大load   factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。

使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”:  
Hashtable   numbers   =   new   Hashtable();  
numbers.put(“one”,   new   Integer(1));  
numbers.put(“two”,   new   Integer(2));  
numbers.put(“three”,   new   Integer(3));

要取出一个数,比如2,用相应的key:  
Integer   n   =   (Integer)numbers.get(“two”);  
System.out.println(“two   =   ”   +   n);

由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。

如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。   Hashtable是同步的。

HashMap类  
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null   value和null   key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load   factor过低。

WeakHashMap类  
WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。

HashSet请参考对Set的描述  
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。

Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。  
请注意:必须小心操作可变对象(Mutable   Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

两个通用Set实现是HashSet和TreeSet。要决定用哪一个,那是非常简单明了的。HashSet要快得多(对大多数操作是常数时间之于对数时间(constant   time   vs.   log   time)),   但不提供排序保证。如果你需要使用   SortedSet   中的操作,或者按顺序迭代对你来说是重要的,那么请使用   TreeSet。   否则,使用   HashSet。   在大多数时间都不使用   HashSet   ,对你来说是个公平的赌博。

关于HashSet,有一件事应该牢记,即就条目数和容量之和来讲,迭代是线性的。因此,如果迭代性能很重要,那就应该慎重选择一个适当的初始容量。容量选得太大,既浪费空间,也浪费时间。   默认的初试容量是101,   一般来讲,它比你所需要的要多。可以使用   int   构造函数来指定初始容量。要分配   HashSet   的初始容量为17:

Set  s=  new  HashSet(17);

HashSets另有一个称作   装载因数(load   factor)的"调整参数(tuning   parameter)"   。如果你非常在乎你的HashSet的空间的使用,请阅读HashSet文本以获取详细信息。否则,就使用默认值吧。如果你接受默认装载因数,但你确实又想指定初始容量,那么,选一个大约是你期望你的   Set   将增长到的容量的两倍的数。如果你的猜测不着边,它也可以增长,或只是浪费一点空间。但都没有大问题。如果你知道有关正确尺寸的一个最佳值,用它吧;如果不知道,那就使用一个旧的值,或使用一个偶数值。它真的不是非常重要。这些事情只能使   HashSet   稍稍变好一点点。

TreeSet没有调整参数。除clone之外,HashSet和TreeSet都仅有那些由它们各自的接口所要求的操作(Set和TreeSet),而没有任何别的操作。

(0)

相关推荐

  • java中Hashtable和HashMap的区别分析

    1.Hashtable是Dictionary的子类, 复制代码 代码如下: public class Hashtable<K,V>     extends Dictionary<K,V>     implements Map<K,V>, Cloneable, java.io.Serializable HashMap: 复制代码 代码如下: public class HashMap<K,V>    extends AbstractMap<K,V> 

  • java HashMap通过value反查key的代码示例

    复制代码 代码如下: import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class MapValueGetKey {  public static void main(String[] args) {    Map map = new HashMap<>();    map.put(1,&qu

  • Java开发之HashMap的使用和遍历

    Java开发之HashMap的使用和遍历 1:使用HashMap的一个简单例子 package com.pb.collection; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.Map.Entry; public class HashMapDemo { public static void main(String[] args) { HashMap<Stri

  • 浅析Java中Map与HashMap,Hashtable,HashSet的区别

    HashTable和HashMap区别 第一,继承的父类不同.Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类.但二者都实现了Map接口. 复制代码 代码如下: public class Hashtable<K,V>extends Dictionary<K,V>implements Map<K,V>, Cloneable, Serializable public class HashMap<K,V>extends

  • java遍历HashMap简单的方法

    本文实例讲述了java遍历HashMap简单的方法.分享给大家供大家参考.具体实现方法如下: import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class HashSetTest { public static void main(String[] args) { HashMap map = new HashMap(); map.put("a", "aa"

  • Java中HashMap和TreeMap的区别深入理解

    首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对. HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的). HashMap 非线程安全 TreeMap 非线程安全 线程安全 在Java里,线程安全一般体

  • JAVA HashMap详细介绍和示例

    第1部分 HashMap介绍HashMap简介HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口.HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,HashMap中的映射不是有序的.HashMap 的实例有两个参数影响其性能:"初始容量" 和 "加载因子".容量

  • Java中HashMap和Hashtable及HashSet的区别

    Hashtable类   Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value. 添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数. Hashtable通过initial   capacity和load   factor两个参数调整性能.通常缺省的load   factor   0.75较好地实现了时间和空间的均衡.增大load   factor可以节省空间但

  • Java中HashMap和Hashtable的区别浅析

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable. HashMap允许将null作为一个entry的key或者value,而Hashtable不允许. HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey.因为contains方法容易让人引起误解. Hashtable继承自Dict

  • java 中HashMap、HashSet、TreeMap、TreeSet判断元素相同的几种方法比较

    java 中HashMap.HashSet.TreeMap.TreeSet判断元素相同的几种方法比较 1.1     HashMap 先来看一下HashMap里面是怎么存放元素的.Map里面存放的每一个元素都是key-value这样的键值对,而且都是通过put方法进行添加的,而且相同的key在Map中只会有一个与之关联的value存在.put方法在Map中的定义如下. V put(K key, V value); 它用来存放key-value这样的一个键值对,返回值是key在Map中存放的旧va

  • java中Hashmap的get方法使用

    目录 java中Hashmap的get方法 举例 HashMap中get方法的原理 1.首先向get()方法中传递一个key 2.在get()方法中调用hash(key) 3.在get()方法中调用getNode(hash,key)方法 4.getNode()方法中 java中Hashmap的get方法 map中存储的是键值对,也就是说通过set方法进行参数和值的存储,之后通过get"键"的形式进行值的读取. 举例 Map map = new Hashmap();//创建一个map m

  • java中vector与hashtable操作实例分享

    众所周知,java中vector与hashtable是线程安全的,主要是java对两者的操作都加上了synchronized,也就是上锁了.因此 在vector与hashtable的操作是不会出现问题.但是有一种情况:就是将一个hashtable copy到另一个hashtable时,假如使用putAll方法的花,会抛出一个 java.util.ConcurrentModificationException异常.先上代码: TestSync.java 复制代码 代码如下: public clas

  • java 中HashMap实现原理深入理解

    1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端.       数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1):数组的特点是:寻址容易,插入和删除困难: 链表 链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N).链表的特点是:寻址困难,插入和删除容易. 哈希表 那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提

  • Java中HashMap里面key为null存放到哪

    我们知道HashMap集合是允许存放null值的 hashMap是根据key的hashCode来寻找存放位置的,那当key为null时, 怎么存储呢? 在put方法里头,其实第一行就处理了key=null的情况. // HashMap的put方法 public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) // key为null调用putForNull

  • 浅谈java中HashMap键的比较方式

    先看一个例子 Integer integer=12344; Integer integer1=12344; 在Java中Integer 和Integer1是不相等的,但是如果再执行如下语句 map.put(integer, 1); map.put(integer1, 2); 会发现2会把1覆盖,问题来了,明明是两个不同的对象,为什么,2会把1覆盖呢? 我们看HashMap中添加键的源代码,如下 可以发现我们传进来的键交给了一个hash的成员方法区处理,这里我们看看hash方法的源码 哦,看到这里

  • Java中HashMap的初始容量设置方式

    Java中HashMap的初始容量设置 根据阿里巴巴Java开发手册上建议HashMap初始化时设置已知的大小,如果不超过16个,那么设置成默认大小16: 集合初始化时, 指定集合初始值大小. 说明: HashMap使用HashMap(int initialCapacity)初始化 正例: initialCapacity = (需要存储的元素个数 / 负载因子) + 1.注意负载因子(即loader factor)默认为0.75, 如果暂时无法确定初始值大小,请设置为16(即默认值). 反例:

  • java中HashMap的7种遍历方式与性能分析

    目录 1.遍历方式 1.1 迭代器 EntrySet 1.2 迭代器 KeySet 1.3 ForEach EntrySet 1.4 ForEach KeySet 1.5 Lambda 表达式 1.6 Stream API 单线程 1.7 Stream API 多线程 1.8 代码汇总 2.性能分析 2.1 引入依赖 2.2 编写测试类 2.3 测试结果 2.4 分析 2.5 总结 1.遍历方式 1.1 迭代器 EntrySet /** * 1. 迭代器 EntrySet */ @Test pu

随机推荐