HashMap,LinkedHashMap和TreeMap之间的区别
Java中的HashMap
, LinkedHashMap
和TreeMap
什么区别? 我没有看到任何输出差异,因为所有三个都有keySet
和values
。 什么是Hashtable
?
Map m1 = new HashMap(); m1.put("map", "HashMap"); m1.put("schildt", "java2"); m1.put("mathew", "Hyden"); m1.put("schildt", "java2s"); print(m1.keySet()); print(m1.values()); SortedMap sm = new TreeMap(); sm.put("map", "TreeMap"); sm.put("schildt", "java2"); sm.put("mathew", "Hyden"); sm.put("schildt", "java2s"); print(sm.keySet()); print(sm.values()); LinkedHashMap lm = new LinkedHashMap(); lm.put("map", "LinkedHashMap"); lm.put("schildt", "java2"); lm.put("mathew", "Hyden"); lm.put("schildt", "java2s"); print(lm.keySet()); print(lm.values());
所有三个类都实现了Map
接口,并提供了大部分相同的function。 最重要的区别是通过条目迭代的顺序:
-
HashMap
对迭代顺序做了绝对的保证。 当新的元素被添加时,它可以(甚至将会)完全改变。 -
TreeMap
将根据它们的compareTo()
方法(或外部提供的Comparator
)根据键的“自然顺序”进行迭代。 此外,它还实现SortedMap
接口,其中包含依赖于此sorting顺序的方法。 -
LinkedHashMap
将按照条目放入地图的顺序迭代
“散列表”是基于散列的地图的通用名称。 在Java API的上下文中, Hashtable
是在集合框架存在之前Java 1.1以前的一个过时的类。 它不应该再被使用了,因为它的API混淆了重复function的过时方法,并且它的方法是同步的(这会降低性能并且通常是无用的)。 使用ConcurrrentHashMap而不是Hashtable。
我更喜欢视觉呈现:
╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗ ║ Property ║ HashMap ║ TreeMap ║ LinkedHashMap ║ ╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣ ║ ║ no guarantee order ║ sorted according ║ ║ ║ Order ║ will remain constant║ to the natural ║ insertion-order ║ ║ ║ over time ║ ordering ║ ║ ╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣ ║ Get/put ║ ║ ║ ║ ║ remove ║ O(1) ║ O(log(n)) ║ O(1) ║ ║ containsKey ║ ║ ║ ║ ╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣ ║ ║ ║ NavigableMap ║ ║ ║ Interfaces ║ Map ║ Map ║ Map ║ ║ ║ ║ SortedMap ║ ║ ╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣ ║ ║ ║ ║ ║ ║ Null ║ allowed ║ only values ║ allowed ║ ║ values/keys ║ ║ ║ ║ ╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣ ║ ║ Fail-fast behavior of an iterator cannot be guaranteed ║ ║ Fail-fast ║ impossible to make any hard guarantees in the presence of ║ ║ behavior ║ unsynchronized concurrent modification ║ ╠══════════════╬═════════════════════╦═══════════════════╦═════════════════════╣ ║ ║ ║ ║ ║ ║Implementation║ buckets ║ Red-Black Tree ║ double-linked ║ ║ ║ ║ ║ buckets ║ ╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣ ║ Is ║ ║ ║ synchronized ║ implementation is not synchronized ║ ╚══════════════╩═══════════════════════════════════════════════════════════════╝
所有这三个代表从唯一键到值的映射,因此实现了Map接口。
-
HashMap是一个基于密钥散列的映射。 它支持O(1)get / put操作。 密钥必须具有
hashCode()
和equals()
一致实现才能工作。 -
LinkedHashMap与HashMap非常相似,但它增加了对项目添加(或访问)顺序的了解,因此迭代顺序与插入顺序(或访问顺序,取决于构造参数)相同。
-
TreeMap是一个基于树的映射。 它的put / get操作占用O(log n)时间。 它要求项目有一些比较机制,可以用Comparable或Comparator。 迭代次序由这个机制决定。
查看下图中每个类在类层次结构中的位置( 较大的一个 )。 TreeMap实现SortedMap
和NavigableMap
而HashMap
则不实现。
HashTable
已经过时,应该使用相应的ConcurrentHashMap
类。
只是从我自己的地图经验的一些input,我什么时候会使用每一个:
- HashMap – 在寻找最佳性能(快速)实现时最有用。
- TreeMap(SortedMap接口) – 当我关心能够按照我定义的特定顺序对键进行sorting或遍历时,最有用。
- LinkedHashMap – 结合TreeMap保证sorting的优点,而不增加维护TreeMap的成本。 (它几乎和HashMap一样快)。 特别的是,LinkedHashMap通过重写
removeEldestEntry()
方法也为创build一个Cache对象提供了一个很好的起点。 这使您可以使用您定义的某些条件创build可以使数据过期的Cache对象。
HashMap中
- 它具有配对值(键,值)
- 没有重复键值
- 无序未sorting
- 它允许一个空键和多个空值
哈希表
- 与散列图相同
- 它不允许空键和空值
LinkedHashMap的
- 它是地图实现的有序版本
- 基于链表和哈希数据结构
TreeMap的
- 有序和分类的版本
- 基于哈希数据结构
HashMap对迭代次序做了绝对的保证。 当新的元素被添加时,它可以(甚至将会)完全改变。 TreeMap将根据它们的compareTo()方法(或外部提供的比较器)根据键的“自然顺序”进行迭代。 此外,它还实现SortedMap接口,其中包含依赖于此sorting顺序的方法。 LinkedHashMap将按照条目放入地图的顺序迭代
看看性能如何变化..
树图是Sorted地图的一个实现。 由于自然sorting,put,get和containsKey操作的复杂度为O(log n)
让我简单说一下:
- HashMap被实现为一个哈希表,并且没有关键或值的sorting。
- TreeMap是基于红黑树结构实现的,按键sorting。
- LinkedHashMap保留了广告订单
- 与HashMap相比, Hashtable是同步的。 它有一个同步开销。这是如果程序是线程安全的,应该使用HashMap的原因。
@Amit: SortedMap
是一个接口,而TreeMap
是一个实现SortedMap
接口的类。 这意味着如果遵循SortedMap
要求其实现者执行的协议。 除非实现为search树,否则树不能为您提供有序的数据,因为树可以是任何种类的树。 因此,为了使TreeMap像sorting顺序一样工作,它实现了SortedMap(例如二进制search树BST,AVL和RB树平衡BST,甚至三元search树 – 主要用于有序迭代search)。
public class TreeMap<K,V> extends AbstractMap<K,V> implements SortedMap<K,V>, Cloneable, Serializable
在NUT-SHELL HashMap
:给出了O(1)中的数据,没有sorting
TreeMap
:在O(log N)中给出数据,基数为2
LinkedHashMap
:是带有链表的哈希表(想到索引 – SkipList)能够以数据插入树的方式存储数据。 最适合实施LRU(最近最less使用)。
所有三个类HashMap
, TreeMap
和LinkedHashMap
实现java.util.Map
接口,并表示从唯一键到值的映射。
HashMap中
-
HashMap
包含基于键的值。 -
它只包含独特的元素。
-
它可能有一个空键和多个空值。
-
它没有维持秩序 。
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
LinkedHashMap的
-
LinkedHashMap
包含基于密钥的值。 - 它只包含独特的元素。
- 它可能有一个空键和多个空值。
-
和HashMap一样,而不是维护插入顺序 。 //见下面的课程减速
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
TreeMap的
-
TreeMap
包含基于键的值。 它实现了NavigableMap接口并扩展了AbstractMap类。 - 它只包含独特的元素。
- 它不能有空键,但可以有多个空值。
-
它与
HashMap
相同,而是保持升序 (使用键的自然顺序sorting)。public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable
哈希表
- 一个Hashtable是一个列表数组。 每个列表被称为一个桶。 bucket的位置通过调用hashcode()方法来标识。 散列表包含基于键的值。
- 它只包含独特的元素。
- 它可能没有任何空键或值。
- 它是同步的 。
-
这是一个遗产类。
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
参考: http : //javarevisited.blogspot.in/2015/08/difference-between-HashMap-vs-TreeMap-vs-LinkedHashMap-Java.html
这些是相同接口的不同实现。 每个实现都有一些优点和缺点(快速插入,慢search),反之亦然。
有关详细信息,请查看TreeMap , HashMap , LinkedHashMap的javadoc。
所有提供一个键 – >值映射和一个方法来遍历键。 这些类之间最重要的区别是时间保证和密钥的sorting。
- HashMap提供0(1)查找和插入。 但是,如果您遍历键,则键的sorting基本上是任意的。 它由一系列链表实现。
- TreeMap提供O(log N)查找和插入。 密钥是有序的,所以如果你需要按照sorting顺序遍历密钥,你可以。 这意味着键必须实现Comparable接口.TreeMap由红黑树实现。
- LinkedHashMap提供0(1)查找和插入。 按键按其插入顺序sorting。 它通过双链接桶实施。
假设你将一个空的TreeMap,HashMap和LinkedHashMap传递给下面的函数:
void insertAndPrint(AbstractMap<Integer, String> map) { int[] array= {1, -1, 0}; for (int x : array) { map.put(x, Integer.toString(x)); } for (int k: map.keySet()) { System.out.print(k + ", "); } }
每个的输出将如下所示。
对于HashMap,在我自己的testing中,输出是{0,1,-1},但它可以是任何顺序。 订货不保证。
Treemap的输出是{-1,0,1}
LinkedList,输出是{1,-1,0}
HashMap中
可以包含一个空键。
HashMap没有维护顺序。
TreeMap的
TreeMap不能包含任何空键。
TreeMap维护升序。
LinkedHashMap的
LinkedHashMap可用于维护插入顺序,将键插入到Map中,或者也可用于维护访问顺序,在其上访问键。
例子 ::
1)HashMap map = new HashMap();
map.put(null, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir");`enter code here` map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); }
2)TreeMap map = new TreeMap();
map.put(1, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir"); map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); }
3)LinkedHashMap map = new LinkedHashMap();
map.put(1, "Kamran"); map.put(2, "Ali"); map.put(5, "From"); map.put(4, "Dir"); map.put(3, "Lower"); for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); }