dma*_*iii 3604 java collections hashtable hashmap
Java中的a HashMap和a有什么区别Hashtable?
哪个非线程应用程序更有效?
Jos*_*own 3648
Java HashMap和HashtableJava 之间存在一些差异:
Hashtable是同步的,而HashMap不是.这HashMap对非线程应用程序更有利,因为非同步对象通常比同步对象执行得更好.
Hashtable不允许null键或值. HashMap允许一个null键和任意数量的null值.
HashMap的子类之一是LinkedHashMap,所以如果您想要可预测的迭代顺序(默认情况下是插入顺序),您可以轻松地换出HashMapfor a LinkedHashMap.如果你使用的话,这并不容易Hashtable.
由于同步不是你的问题,我建议HashMap.如果同步成为问题,您也可以查看ConcurrentHashMap.
ser*_*g10 652
请注意,许多答案都表明Hashtable已同步. 在实践中,这很少给你买. 访问器/ mutator方法上的同步将停止两个线程同时添加或从地图中删除,但在现实世界中,您将经常需要额外的同步.
一个非常常见的习语是"检查然后放" - 即在地图中查找条目,如果它尚不存在则添加它.无论您使用Hashtable还是HashMap,这都不是原子操作.
可以通过以下方式获得等效同步的HashMap:
Collections.synchronizedMap(myMap);
Run Code Online (Sandbox Code Playgroud)
但要正确实现此逻辑,您需要额外的表单同步:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
Run Code Online (Sandbox Code Playgroud)
即使迭代Hashtable的条目(或Collections.synchronizedMap获得的HashMap)也不是线程安全的,除非您还通过附加同步保护Map不被修改.
ConcurrentMap接口的实现(例如ConcurrentHashMap)通过包含线程安全的check-then-act语义来解决其中的一些问题,例如:
ConcurrentMap.putIfAbsent(key, value);
Run Code Online (Sandbox Code Playgroud)
abe*_*t80 342
Hashtable被认为是遗留代码.没有什么Hashtable可以使用HashMap或推导无法完成HashMap,所以对于新代码,我认为没有任何理由回到Hashtable.
小智 172
在访谈中经常会问这个问题,以检查候选人是否理解收集类的正确用法,并了解可用的替代解决方案.
关于一些重要条款的说明
HashMap可以同步
HashMap
Map提供了Collection视图,而不是通过Enumeration对象直接支持迭代.集合视图极大地增强了界面的表现力,如本节后面所述.Map允许您迭代键,值或键值对; Hashtable不提供第三种选择.Map提供了一种在迭代过程中删除条目的安全方法; Hashtable没有.最后,Map修复了Hashtable界面中的一个小缺陷.Hashtable有一个名为contains的方法,如果Hashtable包含给定值,则返回true.鉴于其名称,如果Hashtable包含给定键,则您希望此方法返回true,因为该键是Hashtable的主要访问机制.Map接口通过重命名方法containsValue消除了这种混淆的来源.此外,这提高了界面的一致性 - containsValue parallels containsKey.
Apo*_*isp 124
HashMap:Map使用哈希代码索引数组的接口的实现.
Hashtable:嗨,1998年叫.他们想要回收他们的集合API.
说真的,你最好远离Hashtable完全.对于单线程应用程序,您不需要额外的同步开销.对于高度并发的应用程序,偏执同步可能会导致饥饿,死锁或不必要的垃圾收集暂停.就像Tim Howland指出的那样,你可以ConcurrentHashMap改用它.
roo*_*ler 67
已发布许多好的答案.我添加了一些新的点并总结了它.
HashMap和Hashtable两个用于存储在键和值形式的数据.两者都使用散列技术来存储唯一键.但是下面给出了HashMap和Hashtable类之间的许多差异.
HashMap中
HashMap是非同步的.它不是线程安全的,如果没有适当的同步代码,就无法在许多线程之间共享. HashMap 允许一个空键和多个空值. HashMap 是JDK 1.2中引入的新类. HashMap 很快 HashMap通过调用此代码使其同步Map m = Collections.synchronizedMap(HashMap); HashMap 由Iterator遍历. HashMap是快速失败的. HashMap 继承AbstractMap类. 哈希表
Hashtable是同步的.它是线程安全的,可以与许多线程共享. Hashtable 不允许任何null键或值. Hashtable 是一个遗产类. Hashtable 是慢的. Hashtable 是内部同步的,不能不同步. Hashtable 由Enumerator和Iterator遍历. Hashtable不是快速失败的. Hashtable 继承Dictionary类.进一步阅读Java中的HashMap和Hashtable有什么区别?
Mil*_*s D 47
Hashtable类似于HashMap并具有类似的界面.HashMap除非您需要支持旧应用程序或需要同步,否则建议您使用,因为Hashtables方法是同步的.因此,在您的情况下,因为您不是多线程,HashMaps所以最好的选择.
小智 34
散列表和散列映射之间的另一个关键区别是HashMap中的Iterator是快速失败的,而Hashtable的枚举器不是,如果任何其他Thread通过添加或删除除Iterator自己的remove()方法之外的任何元素而在结构上修改映射,则抛出ConcurrentModificationException.但这不是一种保证行为,将由JVM尽最大努力完成."
我的来源:http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
pwe*_*wes 34
除了这里已经提到的所有其他重要方面,Collections API(例如Map接口)一直在被修改,以符合Java规范的"最新和最好"的补充.
例如,比较Java 5 Map迭代:
for (Elem elem : map.keys()) {
elem.doSth();
}
Run Code Online (Sandbox Code Playgroud)
与旧的Hashtable方法相比:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
Run Code Online (Sandbox Code Playgroud)
在Java 1.8中,我们还承诺能够构建和访问HashMaps,就像在旧的脚本语言中一样:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
Run Code Online (Sandbox Code Playgroud)
更新:不,他们不会降落在1.8 ...... :(
Project Coin的集合增强功能将在JDK8中进行吗?
ala*_*inm 28
HashTable是同步的,如果您在单个线程中使用它,则可以使用HashMap,这是一个不同步的版本.非同步对象通常更具性能.顺便说一下,如果多个线程同时访问HashMap,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步.您可以使用以下方法将未同步的地图包装在同步的地图中:
Map m = Collections.synchronizedMap(new HashMap(...));
Run Code Online (Sandbox Code Playgroud)HashTable只能包含非空对象作为键或值.HashMap可以包含一个空键和空值.
Map返回的迭代器是快速失败的,如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出一个ConcurrentModificationException.因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.而 Hashtable的键和元素方法返回的枚举并不是快速失败的.
HashTable和HashMap是Java Collections Framework的成员(自Java 2平台v1.2起,HashTable被改进以实现Map接口).
HashTable被认为是遗留代码,如果需要线程安全的高度并发实现,文档建议使用ConcurrentHashMap代替Hashtable.
HashMap不保证返回元素的顺序.对于HashTable,我猜它是一样的,但我不完全确定,我找不到明确说明这一点的资源.
Sky*_*ker 28
HashMap并且Hashtable具有显着的算法差异.之前没有人提到这一点,所以这就是我提出这个问题的原因.HashMap将构造一个具有两个大小的哈希表,动态增加它,使得你在任何桶中最多有八个元素(冲突),并且会很好地激发一般元素类型的元素.但是,Hashtable如果你知道自己在做什么,那么实现提供了对哈希的更好和更精细的控制,即你可以使用最接近的质数来修复表大小到你的值域大小,这将导致比HashMap更好的性能,即更少的冲突对于某些情况.
除了在这个问题中广泛讨论的显而易见的差异之外,我认为Hashtable是一个"手动驱动"汽车,你可以更好地控制散列和HashMap作为通常表现良好的"自动驱动"对应物.
Yas*_*ash 22
A Collection- 有时称为容器 - 只是一个将多个元素组合成一个单元的对象.Collections用于存储,检索,操作和传递聚合数据.集合框架W是用于表示和操作集合的统一体系结构.
的HashMap JDK1.2和Hashtable JDK1.0,两者都用来表示一组在表示的对象的<Key, Value>一对.每<Key, Value>对称为Entry对象.参赛作品的收集是由对象简称HashMap和Hashtable.集合中的键必须是唯一的或独特的.[因为它们用于检索特定键的映射值.集合中的值可以重复.]
« 超类,遗产和收藏框架成员
Hashtable是一个引入的遗留类JDK1.0,它是Dictionary类的子类.从JDK1.2Hashtable重新设计实现Map接口以构成集合框架的成员.HashMap从一开始就是Java Collection Framework的成员JDK1.2.HashMap是AbstractMap类的子类.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
Run Code Online (Sandbox Code Playgroud)
« 初始容量和负载系数
容量是哈希表中的桶数,初始容量只是创建哈希表时的容量.请注意,哈希表是打开的:在" hashcollision" 的情况下,单个存储桶存储多个条目,必须按顺序搜索.加载因子是在自动增加容量之前允许哈希表获取的完整程度的度量.
HashMap使用默认初始容量(16)和默认加载因子(0.75)构造一个空哈希表.Hashtable在何处使用默认初始容量(11)和加载因子/填充率(0.75)构造空哈希表.
« 哈希冲突情况下的结构修改
HashMap,Hashtable在哈希冲突的情况下,它们存储在链表的映射条目.从Java8 forHashMap if hash bucket超过某个阈值,该桶将从中切换linked list of entries to a balanced tree.它改善了从O(n)到O(log n)的最坏情况性能.在将列表转换为二叉树时,哈希码用作分支变量.如果同一个存储桶中有两个不同的哈希码,则一个被认为更大,并且位于树的右侧,另一个位于左侧.但是当两个哈希码都相等时,HashMap假设密钥是可比较的,并比较密钥以确定方向,以便可以维持某个顺序.制作HashMap 可比较的钥匙是一个好习惯.在添加条目时,如果存储桶大小达到TREEIFY_THRESHOLD = 8将条目的链接列表转换为平衡树,则在删除小于TREEIFY_THRESHOLD 和最多的条目时,UNTREEIFY_THRESHOLD = 6会将平衡树重新转换为链接的条目列表.Java 8 SRC,stackpost
« 集合视图迭代,失败快速和失败安全
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Run Code Online (Sandbox Code Playgroud)
Iterator是一种快速失败的性质.即如果在迭代时修改集合而不是它自己的remove()方法,则抛出ConcurrentModificationException.凡为Enumeration是故障安全性的.如果在迭代时修改了集合,则不会抛出任何异常.
根据Java API Docs,Iterator始终优于Enumeration.
注意: Enteration接口的功能由Iterator接口复制.此外,Iterator添加了一个可选的删除操作,并且具有更短的方法名称.新实现应考虑使用Iterator而不是Enumeration.
在Java 5中引入了ConcurrentMap接口:ConcurrentHashMap- ConcurrentMap由哈希表支持的高度并发,高性能的实现.执行检索时,此实现永远不会阻塞,并允许客户端选择更新的并发级别.它旨在作为以下内容的替代品Hashtable:除了实现之外ConcurrentMap,它还支持所有特有的"遗留"方法Hashtable.
每个HashMapEntrys值都是易失性的,从而确保了竞争修改和后续读取的细粒度一致性; 每次阅读都反映了最近完成的更新
迭代器和枚举是失败安全的 - 自迭代器/枚举创建以来某些时候反映状态; 这允许以降低一致性为代价同时进行读取和修改.它们不会抛出ConcurrentModificationException.但是,迭代器设计为一次只能由一个线程使用.
类似Hashtable但不同HashMap,这个类不允许空用作键或值.
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
« 空键和空值
HashMap允许最多一个空键和任意数量的空值.如果Hashtable不允许甚至单个null键和null值,如果键或值为null,则抛出NullPointerException.例
« 同步,线程安全
Hashtable在内部同步.因此,Hashtable在多线程应用程序中使用它是非常安全的.哪里HashMap没有内部同步.因此,HashMap在没有外部同步的多线程应用程序中使用是不安全的.您可以HashMap使用Collections.synchronizedMap()方法在外部进行同步.
« 表现
由于Hashtable在内部同步,这Hashtable比稍微慢一点HashMap.
@看到
Rah*_*thi 16
1. Hashmap并HashTable存储密钥和值.
2. Hashmap可以存储一个密钥null.Hashtable不能存储null.
3. HashMap未同步但Hashtable已同步.
4. HashMap可以同步Collection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
Run Code Online (Sandbox Code Playgroud)
Kos*_*ias 15
除了已经提到的差异,应该指出的是,自从Java 8,HashMap动态替换每个桶使用树节点(红黑树)的节点(链表),这样,即使高哈希冲突存在,最坏的情况下,当搜索是
O(log(n))对于HashMap Vs O(n)in Hashtable.
*上述改进还没有被应用到Hashtable还没有,但只HashMap,LinkedHashMap和ConcurrentHashMap.
仅供参考,目前,
TREEIFY_THRESHOLD = 8 :如果存储桶包含8个以上的节点,则链表将转换为平衡树.UNTREEIFY_THRESHOLD = 6 :当桶变得太小(由于删除或调整大小)时,树将转换回链表.use*_*551 13
HashTable和HashMaps有5个基本区别.
Shr*_*ari 12
我的小贡献:
首先,也是最显著之间的不同
Hashtable和HashMap是,HashMap是不是线程安全的,同时Hashtable是一个线程安全的集合.第二个重要的区别是
Hashtable和HashMap性能,因为HashMap它不同步它表现得更好Hashtable.关于第三个区别
HashtableVSHashMap是Hashtable已经过时的类,你应该使用ConcurrentHashMap代替HashtableJava编写的.
HashMap:它是java.util包中可用的类,它用于以键和值格式存储元素.
Hashtable:它是一个遗留类,在集合框架中被识别.
1)Hashtable是同步的,而hashmap不是.2)另一个区别是HashMap中的迭代器是故障安全的,而Hashtable的枚举器则不是.如果你在迭代时更改地图,你就会知道.
3)HashMap允许空值,而Hashtable则不允许.
HashMap和HashTable
1)Hashtable和Hashmap实现java.util.Map接口2)Hashmap和Hashtable都是基于散列的集合.并致力于散列.所以这些是HashMap和HashTable的相似之处.
1)第一个区别是HashMap不是线程安全的,而HashTable是ThreadSafe
2)HashMap更好,因为它不是线程安全的.虽然Hashtable性能明智并不好,因为它是线程安全的.所以多线程不能同时访问Hashtable.
由于Java中的Hashtable是Dictionary类的子类,由于Map接口的存在,Dictionary类现已过时,因此不再使用它。此外,对于实现 Map Interface 的类来说,没有什么是用 Hashtable 可以做到的。
Hashtable:
Hashtable是一种保留键值对值的数据结构.它不允许键和值都为null.NullPointerException如果添加空值,您将得到一个.它是同步的.所以它带来了它的成本.只有一个线程可以在特定时间访问HashTable.
示例:
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
Run Code Online (Sandbox Code Playgroud)
HashMap的:
HashMap类似于Hashtable,但它也接受键值对.它允许键和值都为null.它的性能更好HashTable,因为它是unsynchronized.
例:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
Run Code Online (Sandbox Code Playgroud)
古老而经典的话题,只想添加这个有用的博客来解释这一点:
http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
Manish Chhabra 的博客
HashMap 和 Hashtable 的 5 个主要区别
HashMap 和 Hashtable 都实现了 java.util.Map 接口,但 Java 开发人员必须了解一些差异才能编写更高效的代码。从 Java 2 平台 v1.2 开始,对 Hashtable 类进行了改造以实现 Map 接口,使其成为 Java Collections Framework 的成员。
HashMap 和 Hashtable 的主要区别之一是 HashMap 是非同步的,而 Hashtable 是同步的,这意味着 Hashtable 是线程安全的,可以在多个线程之间共享,但 HashMap 不能在没有适当同步的情况下在多个线程之间共享。Java 5 引入了 ConcurrentHashMap,它是 Hashtable 的替代品,提供比 Java 中的 Hashtable 更好的可扩展性。同步意味着在一个时间点只有一个线程可以修改哈希表。基本上,这意味着在对哈希表执行更新之前,任何线程都必须获取对象上的锁,而其他线程将等待释放锁。
HashMap 类大致等同于 Hashtable,除了它允许空值。(HashMap 允许空值作为键和值,而 Hashtable 不允许空值)。
HashMap 与 Hashtable 之间的第三个显着区别是 HashMap 中的 Iterator 是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除迭代器自己的元素之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException 异常。 ) 方法。但这不是保证的行为,JVM 会尽最大努力完成。这也是Java中Enumeration和Iterator的一个重要区别。
Hashtable 和 HashMap 之间更显着的区别是,由于线程安全和同步,如果在单线程环境中使用,Hashtable 比 HashMap 慢得多。因此,如果您不需要同步并且 HashMap 仅由一个线程使用,那么它在 Java 中执行 Hashtable。
HashMap 不保证映射的顺序会随着时间的推移保持不变。
请注意,HashMap 可以通过以下方式同步
Run Code Online (Sandbox Code Playgroud)Map m = Collections.synchronizedMap(hashMap);总而言之,Java 中的 Hashtable 和 HashMap 之间存在显着差异,例如线程安全和速度,并且仅在您绝对需要线程安全时才使用 Hashtable,如果您正在运行 Java 5,请考虑在 Java 中使用 ConcurrentHashMap。
同步或线程安全:
Hash Map 不是同步的,因此它不是线程安全的,并且它不能在没有适当的同步块的情况下在多个线程之间共享,而 Hashtable 是同步的,因此它是线程安全的。
空键和空值:
HashMap 允许一个空键和任意数量的空值。Hashtable 不允许空键或值。
迭代值:
HashMap 中的迭代器是一个快速失败的迭代器,而 Hashtable 的枚举器不是,如果任何其他线程通过添加或删除除迭代器自己的 remove() 方法之外的任何元素在结构上修改映射,则抛出 ConcurrentModificationException 。
超类和遗产:
HashMap 是 AbstractMap 类的子类,而 Hashtable 是 Dictionary 类的子类。
性能:
由于 HashMap 不是同步的,它比 Hashtable 更快。
请参阅http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-java以获取与 Java 集合相关的示例和面试问题和测验
| 归档时间: |
|
| 查看次数: |
1492633 次 |
| 最近记录: |