Differences between HashMap and Hashtable?
在Java中EDCOX1与0的EDCOX1和1的区别是什么?
哪个对于非线程应用程序更有效?
在Java中,EDOCX1与1的EDCX1和EDCX1之间有几个不同之处:
hashmap的子类之一是
因为同步对您来说不是问题,所以我建议您使用
注意,很多答案都表示哈希表是同步的。实际上,这对你没什么好处。同步在访问器/转换器上,方法将停止两个线程同时添加或从映射中删除,但在现实世界中,您通常需要额外的同步。
一个非常常见的习惯用法是"检查然后放入",即在
等效同步的
1 |
但要正确实现此逻辑,需要对表单进行额外的同步:
1 2 3 4 | synchronized(myMap) { if (!myMap.containsKey("tomato")) myMap.put("tomato","red"); } |
即使迭代
1 | ConcurrentMap.putIfAbsent(key, value); |
面试中经常会问这个问题,以检查应聘者是否理解集合类的正确用法,是否知道可用的替代解决方案。
一些重要术语的注释
hashmap可以通过以下方式进行同步:
映射提供集合视图,而不是直接支持迭代通过枚举对象。集合视图大大增强了接口的表现性,如本节后面所讨论的。map允许您迭代键、值或键值对;哈希表不提供第三个选项。地图提供了一种安全的方法在迭代过程中删除条目;哈希表没有。最后,map修复了hashtable接口中的一个小缺陷。hashtable有一个名为contains的方法,如果哈希表包含给定值。鉴于它的名字,你会预料到的如果哈希表包含给定的键,则返回true,因为密钥是哈希表的主要访问机制。地图接口通过重命名方法来消除这种混乱源包含价值。此外,这还提高了接口的一致性-containsValue与containsKey并行。
The Map Interface
不过,说真的,你最好还是远离
请记住,在引入Java集合框架(JCF)之前,EDCOX1×0是遗留类,后来被改装以实现EDCOX1×1接口。以东十一〔2〕和以东十一〔3〕也是如此。
因此,在新代码中始终远离它们,因为正如其他人指出的那样,JCF中总是有更好的选择。
下面是Java集合备忘录,您会发现它有用。注意,灰色块包含遗留类hashtable、vector和stack。
除了IZB所说的,
另请注意,
已经发布了很多好的答案。我在增加一些新的观点并总结它。
哈希图
哈希表
进一步阅读HashMap和哈希表在Java中的区别是什么?
看看这个图表。它提供不同数据结构之间的比较,以及hashmap和hashtable。比较准确、清晰、易懂。
Java集合矩阵
hashtable和hashmap的另一个关键区别是,hashmap中的迭代器失败得很快,而hashtable的枚举器不是,如果任何其他线程通过添加或删除迭代器自己的remove()方法以外的任何元素来修改映射,则抛出ConcurrentModificationException。但这不是一个保证的行为,将由JVM尽最大努力来完成。"
我的来源:http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
除了这里已经提到的所有其他重要的方面外,集合API(例如,MAP接口)一直在修改,以符合Java规范的"最新和最伟大的"添加。
例如,比较Java 5映射迭代:
1 2 3 | for (Elem elem : map.keys()) { elem.doSth(); } |
与旧的hashtable方法相比:
1 2 3 4 | for (Enumeration en = htable.keys(); en.hasMoreElements(); ) { Elem elem = (Elem) en.nextElement(); elem.doSth(); } |
在Java 1.8中,我们还承诺能够像旧的脚本语言那样构造和访问哈希图:
1 2 |
更新:不,他们不会在1.8着陆…:(
Project Coin的收藏增强功能将在JDK8中吗?
hashtable是同步的,如果您在单个线程中使用它,那么您可以使用hashmap,这是一个未同步的版本。未同步对象的性能通常会提高一点。另外,如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改了该映射,那么它必须在外部同步。您可以使用以下方法将未同步的映射包装到同步的映射中:
1哈希表只能包含非空对象作为键或值。哈希映射可以包含一个空键和空值。
map返回的迭代器失败得很快,如果在迭代器创建后的任何时候对map进行了结构修改,除了通过迭代器自己的remove方法之外,迭代器将以任何方式抛出
ConcurrentModificationException 。因此,在面对并发修改时,迭代器会快速而清晰地失败,而不是在未来的不确定时间内冒任意、不确定的风险。而hashtable的keys和elements方法返回的枚举不会很快失败。哈希表和HashMap是Java集合框架的成员(自Java 2平台V1.2,哈希表被改装以实现MAP接口)。
hashtable被认为是遗留代码,文档建议在需要线程安全的高度并发实现时使用concurrenthashmap代替hashtable。
hashmap不保证返回元素的顺序。对于hashtable,我想是一样的,但我不完全确定,我找不到明确说明这一点的资源。
除了在这个问题中广泛讨论的明显差异之外,我把hashtable看作是一辆"手动驾驶"的车,在这里您可以更好地控制hashing,而hashmap则是"自动驾驶"的对应物,通常性能良好。
hashtable是同步的,而hashmap不是同步的。这使得hashtable比hashmap慢。
对于非线程应用程序,使用hashmap,因为它们在功能方面是相同的。
根据这里的信息,我建议使用hashmap。我认为最大的好处是Java在迭代时会阻止你修改它,除非你通过迭代器完成它。
?超类、遗留和集合框架成员好的。
hashtable是
1 2 3 | 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 { ... } |
?初始容量和负载系数好的。
容量是哈希表中的存储桶数,初始容量只是创建哈希表时的容量。请注意,哈希表是打开的:在"
hashmap构造一个具有默认初始容量(16)和默认加载因子(0.75)的空哈希表。其中,as hashtable构造具有默认初始容量(11)和加载因子/填充率(0.75)的空hashtable。好的。
好的。
?哈希冲突时的结构修改好的。
?集合视图迭代、快速失败和安全失败好的。
1 2 3 4 5 6 7 8 9 | +--------------------+-----------+-------------+ | | Iterator | Enumeration | +--------------------+-----------+-------------+ | Hashtable | fail-fast | safe | +--------------------+-----------+-------------+ | HashMap | fail-fast | fail-fast | +--------------------+-----------+-------------+ | ConcurrentHashMap | safe | safe | +--------------------+-----------+-------------+ |
根据Java API文档,Iterator总是优于枚举。好的。
注意:枚举接口的功能被迭代器接口复制。此外,迭代器添加了一个可选的移除操作,并且具有较短的方法名。新的实现应该优先考虑使用迭代器来枚举。好的。 在Java 5中引入了CONTURNEXMAP接口:EDCOX1 OR 26 ED-一个高度并行的、高性能的EDCOX1×27实现,它由哈希表支持。此实现在执行检索时从不阻塞,并允许客户端选择更新的并发级别。它的目的是减少对 每 /好的。 迭代器和enumerations是故障安全的状态,都反映在一些点从创造的迭代器所指向的元素/计数的方法;这允许同步读取和modifications的成本减少了一致性。他们不再把concurrentmodificationexception。。。。。。。但是,在自行设计的迭代器是可以使用的只有一个线程在一个时间。
/好的。 但像 /好的。 ???????空和空值. /好的。 /好的。 ???????同步,线程安全的 /好的。 /好的。 ???????的性能 /好的。 作为 /好的。 "看到 /好的。 好的。 对于线程化的应用程序,您通常可以避开ConcurrentHashMap,这取决于您的性能需求。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//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();
}
}
1.
2.
3.
4.
1 2 3 |
除了已经提到的差异之外,应该注意到,自从Java 8以来,EDCOX1(0)动态地替换了每个桶中使用的树节点(红黑树)中的节点(链表),因此即使存在高散列冲突,搜索时最坏的情况也是。
o(log(n))表示
*上述改进尚未应用于
目前,
TREEIFY_THRESHOLD = 8 :如果一个bucket包含8个以上的节点,则链表被转换成平衡树。UNTREEIFY_THRESHOLD = 6 :当存储桶太小(由于删除或调整大小)时,树会转换回链接列表。
hashtable和hashmaps有5个基本区别。
我的小贡献:
First and most significant different between
Hashtable andHashMap is that,HashMap is not thread-safe whileHashtable is a thread-safe collection.Second important difference between
Hashtable andHashMap is performance, sinceHashMap is not synchronized it perform better thanHashtable .Third difference on
Hashtable vsHashMap is thatHashtable is obsolete class and you should be usingConcurrentHashMap in place ofHashtable in Java.
hashtable是JDK中的一个遗留类,不应该再使用了。用Concurrenthashmap替换它的用法。如果您不需要线程安全,请使用hashmap,它不是threadsafe,而是更快、占用更少内存。
hashmap:它是java.util包中可用的类,用于以键和值格式存储元素。
哈希表:它是一个遗留类,在集合框架内被识别。
哈希映射和哈希表
- 关于hashmap和hashtable的一些要点。请阅读以下详细信息。
1)hashtable和hashmap实现java.util.map接口2)hashmap和hashtable都是基于哈希的集合。并致力于散列。所以这些是hashmap和hashtable的相似性。
- hashmap和hashtable有什么区别?
1)第一个区别是hashmap不是线程安全的,而hashtable是线程安全的2)hashmap的性能更好,因为它不是线程安全的。虽然哈希表的性能并不好,因为它是线程安全的。因此多线程不能同时访问哈希表。
1)hashtable是同步的,而hashmap不是同步的。2)另一个区别是hashmap中的迭代器是故障安全的,而hashtable的枚举器不是。如果在迭代器中更改映射,您将知道。
3)hashmap允许空值,hashtable不允许空值。
hashtable是一种保留键值对值的数据结构。它不允许键和值都为空。如果添加空值,您将得到一个
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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)); } } |
HashMap:
hashmap类似于hashtable,但它也接受键值对。它允许键和值都为空。它的性能优于
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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)); } } |
hashmaps为您提供了同步和调试的自由,这要容易得多。
同步或线程安全:
哈希映射不同步,因此它不是线程安全的,如果没有正确的同步块,它不能在多个线程之间共享,而哈希表是同步的,因此它是线程安全的。
空键和空值:
哈希映射允许一个空键和任意数量的空值。哈希表不允许空键或值。
迭代值:
hashmap中的迭代器是一个fail-fast迭代器,而hashtable的枚举器不是,如果任何其他线程通过添加或删除迭代器自己的remove()方法之外的任何元素来修改映射,则抛出ConcurrentModificationException。
超类和传统:
hashmap是abstractmap类的子类,而hashtable是dictionary类的子类。
性能:
因为hashmap不同步,所以比hashtable更快。
参考HTTP://NothPosialA.COM/ToeLe/1020/差异-HasMAP-和HASTABLE在Java中的示例和面试问题和与Java集合相关的问答
hashmap是一个用于以键和值格式存储元素的类。它不是线程安全的。因为它不同步。其中as-hashtable是同步的。hashmap允许空值,但hastable不允许空值。
由于Java中的哈希表是字典类的一个子类,由于映射接口的存在,字典类现在已经过时,不再使用它。此外,对于实现映射接口的类,没有什么是您不能做的,您可以用哈希表来做。
老的和经典的主题,只想添加这个有帮助的博客,解释这一点:
http://blog.manishchabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/
Manish Chhabra的博客
The 5 main differences betwen HashMap and Hashtable
HashMap and Hashtable both implement java.util.Map interface but there
are some differences that Java developers must understand to write
more efficient code. As of the Java 2 platform v1.2, Hashtable class
was retrofitted to implement the Map interface, making it a member of
the Java Collections Framework.One of the major differences between HashMap and Hashtable is that HashMap is non-synchronized whereas Hashtable is synchronized, which
means Hashtable is thread-safe and can be shared between multiple
threads but HashMap cannot be shared between multiple threads without
proper synchronization. Java 5 introduced ConcurrentHashMap which is
an alternative of Hashtable and provides better scalability than
Hashtable in Java.Synchronized means only one thread can modify a hash
table at one point of time. Basically, it means that any thread before
performing an update on a hashtable will have to acquire a lock on the
object while others will wait for lock to be released.The HashMap class is roughly equivalent to Hashtable, except that it permits nulls. (HashMap allows null values as key and value whereas
Hashtable doesn’t allow nulls).The third significant difference between HashMap vs Hashtable is that Iterator in the HashMap is a fail-fast iterator while the
enumerator for the Hashtable is not and throw
ConcurrentModificationException if any other Thread modifies the map
structurally by adding or removing any element except Iterator’s own
remove() method. But this is not a guaranteed behavior and will be
done by JVM on best effort. This is also an important difference
between Enumeration and Iterator in Java.One more notable difference between Hashtable and HashMap is that because of thread-safety and synchronization Hashtable is much slower
than HashMap if used in Single threaded environment. So if you don’t
need synchronization and HashMap is only used by one thread, it out
perform Hashtable in Java.HashMap does not guarantee that the order of the map will remain constant over time.
Note that HashMap can be synchronized by
1In Summary there are significant differences between Hashtable and
HashMap in Java e.g. thread-safety and speed and based upon that only
use Hashtable if you absolutely need thread-safety, if you are running
Java 5 consider using ConcurrentHashMap in Java.
hashtable类是同步的,也就是说,它被设计用于处理多线程或多线程进程的应用程序。在应用程序到进程的经典情况下,同步类的效率较低,因此hashmap类通常更快。hashtable类不接受空值(键或值),而hashmap类允许一个具有空值和尽可能多的空值的键。