HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

来源:互联网 发布:linux安装图形界面命令 编辑:程序博客网 时间:2024/04/28 16:56

原文:http://www.importnew.com/8658.html

Map是最重要的数据结构。这篇文章中,我会带你们看看HashMap, TreeMap, HashTable和LinkedHashMap的区别。

1. Map概览

Java SE中有四种常见的Map实现——HashMap, TreeMap, Hashtable和LinkedHashMap。如果我们使用一句话来分别概括它们的特点,就是:

  • HashMap就是一张hash表,键和值都没有排序。
  • TreeMap以红-黑树结构为基础,键值按顺序排列。
  • LinkedHashMap保存了插入时的顺序。
  • Hashtable是同步的(而HashMap是不同步的)。所以如果在线程安全的环境下应该多使用HashMap,而不是Hashtable,因为Hashtable对同步有额外的开销。

2. HashMap

如果HashMap的键(key)是自定义的对象,那么需要按规则定义它的equals()和hashCode()方法。

class Dog {String color;Dog(String c) {color = c;}public String toString() {return color + " dog";}}public class TestHashMap {public static void main(String[] args) {HashMap hashMap = new HashMap();Dog d1 = new Dog("red");Dog d2 = new Dog("black");Dog d3 = new Dog("white");Dog d4 = new Dog("white");hashMap.put(d1, 10);hashMap.put(d2, 15);hashMap.put(d3, 5);hashMap.put(d4, 20);// print sizeSystem.out.println(hashMap.size());// loop HashMapfor (Entry entry : hashMap.entrySet()) {System.out.println(entry.getKey().toString() + " - " + entry.getValue());}}}

输出

4white dog - 5black dog - 15red dog - 10white dog - 20

注意,我们错误的将”white dogs”添加了两次,但是HashMap却接受了两只”white dogs”。这不合理(因为HashMap的键不应该重复),我们会搞不清楚真正有多少白色的狗存在。

Dog类应该定义如下:

class Dog {String color;Dog(String c) {color = c;}public boolean equals(Object o) {if (this == o) {return true;}if (o instanceof Dog) {return ((Dog) o).color.equals(this.color);}return false;}public int hashCode() {return color.length();}public String toString() {return color + " dog";}}

输出:

3red dog - 10white dog - 20black dog - 15

输出结果如上是因为HashMap不允许有两个相等的元素存在。默认情况下(也就是类没有实现hashCode()和equals()方法时),会使用Object类中的这两个方法。Object类中的hashCode()对于不同的对象会返回不同的整数,而只有两个引用指向的同样的对象时 equals()才会返回true。

3. TreeMap

TreeMap的键按顺序排列。让我们先看个例子看看什么叫作“键按顺序排列”。

class Dog {String color;Dog(String c) {color = c;}public boolean equals(Object o) {if (this == o) {return true;}if (o instanceof Dog) {return ((Dog) o).color.equals(this.color);}return false;}public int hashCode() {return color.length();}public String toString() {return color + " dog";}}public class TestTreeMap {public static void main(String[] args) {Dog d1 = new Dog("red");Dog d2 = new Dog("black");Dog d3 = new Dog("white");Dog d4 = new Dog("white");TreeMap treeMap = new TreeMap();treeMap.put(d1, 10);treeMap.put(d2, 15);treeMap.put(d3, 5);treeMap.put(d4, 20);for (Entry entry : treeMap.entrySet()) {System.out.println(entry.getKey() + " - " + entry.getValue());}}}

输出:

Exception in thread "main" java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable    at java.util.TreeMap.put(Unknown Source)    at collection.TestHashMap.main(TestHashMap.java:35)

因为TreeMap按照键的顺序进行排列对象,所以键的对象之间需要能够比较,所以就要实现Comparable接口。你可以使用String作为键,String已经实现了Comparable接口。

我们来修改下Dog类,让它实现Comparable接口。

class Dog implements Comparable<Dog> {String color;int size;Dog(String c, int s) {color = c;size = s;}public String toString() {return color + " dog";}@Overridepublic int compareTo(Dog o) {return o.size - this.size;}}public class TestTreeMap {public static void main(String[] args) {Dog d1 = new Dog("red", 30);Dog d2 = new Dog("black", 20);Dog d3 = new Dog("white", 10);Dog d4 = new Dog("white", 10);TreeMap treeMap = new TreeMap();treeMap.put(d1, 10);treeMap.put(d2, 15);treeMap.put(d3, 5);treeMap.put(d4, 20);for (Entry entry : treeMap.entrySet()) {System.out.println(entry.getKey() + " - " + entry.getValue());}}}

输出:

red dog - 10black dog - 15white dog - 20

结果根据键的排列顺序进行输出,在我们的例子中根据size排序的。

如果我们将“Dog d4 = new Dog(“white”, 10);”替换成“Dog d4 = new Dog(“white”, 40);”,那么输出会变成:

white dog - 20red dog - 10black dog - 15white dog - 5

这是因为TreeMap使用compareTo()方法来比较键值的大小,size不相等的狗是不同的狗。

4. Hashtable

Java文档写道:

HashMap类和Hashtable类几乎相同,不同之处在于HashMap是不同步的,也允许接受null键和null值。

5. LinkedHashMap

LinkedHashMap is a subclass of HashMap. That means it inherits the features of HashMap. In addition, the linked list preserves the insertion-order.

Let’s replace the HashMap with LinkedHashMap using the same code used for HashMap.

LinkedHashMap是HashMap的子类,所以LinkedHashMap继承了HashMap的一些属性,它在HashMap基础上增加的特性就是保存了插入对象的顺序。

class Dog {String color;Dog(String c) {color = c;}public boolean equals(Object o) {if (this == o) {return true;}if (o instanceof Dog) {return ((Dog) o).color.equals(this.color);}return false;}public int hashCode() {return color.length();}public String toString() {return color + " dog";}}public class TestHashMap {public static void main(String[] args) {Dog d1 = new Dog("red");Dog d2 = new Dog("black");Dog d3 = new Dog("white");Dog d4 = new Dog("white");LinkedHashMap linkedHashMap = new LinkedHashMap();linkedHashMap.put(d1, 10);linkedHashMap.put(d2, 15);linkedHashMap.put(d3, 5);linkedHashMap.put(d4, 20);for (Entry entry : linkedHashMap.entrySet()) {System.out.println(entry.getKey() + " - " + entry.getValue());}}}

输出:

red dog - 10black dog - 15white dog - 20

如果我们使用HashMap的话,输出将会如下,会打乱插入的顺序:

red dog - 10white dog - 20black dog - 15

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 月经期垫卫生巾有边红肿有疹怎么办 四十天拉今天恶露特别多怎么办 顺产侧切出院几天后伤口裂开怎么办 产后十几撕裂用卫生巾疼怎么办 婴儿绑肚脐的棉黏在肚脐上怎么办 割完双眼皮第五天了很痒怎么办 自体脂肪丰胸做完半年有团块怎么办 假体隆胸一个月了躺着睡很硬怎么办 假体隆胸半月俩胸大小不一样怎么办 假体隆胸拆线后还是起不来床怎么办 假体隆胸术后6天 天天胀痛怎么办 阴部大腿根长了个疙瘩有点痛怎么办 加盟费交了总部不做事怎么办 仓鼠从桌子摔下来后走路别扭怎么办 习惯了一个人天天找你聊天怎么办 来完月经外阴湿疹就严重怎么办 宝宝不肯喝开水尿黄黄的怎么办 做阴超做一半发现忘记换套了怎么办 穿裙子时拉链总往下掉怎么办 子宫内膜厚姨妈来的久怎么办 胸小胸罩往上跑肩带往两边掉怎么办 白衣服弄上姨妈血了洗了变黄怎么办 货物丢失了我感觉没丢这么多怎么办 想穿短裙 但是膝盖怕凉怎么办 被老公看到内裤很脏还有屎怎么办 排卵期同房了不知道怀没怀孕怎么办 清理空调时湿纸巾被卷进去怎么办 超市买的尿不湿质量太差怎么办 把卫生巾和衣服一起洗了怎么办 全面屏面对vo华为手机怎么办屏 雅漾喷雾的喷头坏了怎么办 悦诗风吟水里面有小颗粒怎么办 林肯mkz钥匙锁在车内怎么办 八四消毒液弄到衣服上怎么办 微信朋友圈发过的文章想修改怎么办 白色衣服被洗衣液染色了怎么办 准迁证和迁移证不想迁了怎么办 出了迁移证又想迁到其他地方怎么办 高中的会考如果没g合格怎么办 鞋子里自带的鞋垫坏了怎么办 入厕纸把私处伤了一下怎么办?