HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

原创 2016年08月31日 14:34:46

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

1. Map概览

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

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

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

classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
    publicString toString(){   
        returncolor + " dog";
    }
}
 
publicclass TestHashMap {
    publicstatic void main(String[] args) {
        HashMap hashMap = newHashMap();
        Dog d1 = newDog("red");
        Dog d2 = newDog("black");
        Dog d3 = newDog("white");
        Dog d4 = newDog("white");
 
        hashMap.put(d1,10);
        hashMap.put(d2,15);
        hashMap.put(d3,5);
        hashMap.put(d4,20);
 
        //print size
        System.out.println(hashMap.size());
 
        //loop HashMap
        for(Entry entry : hashMap.entrySet()) {
            System.out.println(entry.getKey().toString() + " - " + entry.getValue());
        }
    }
}

输出:

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

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

Dog类应该定义如下:

classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
 
    publicboolean equals(Object o) {
        return((Dog) o).color == this.color;
    }
 
    publicint hashCode() {
        returncolor.length();
    }
 
    publicString toString(){   
        returncolor + " dog";
    }
}

现在输出结果如下:

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

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

来看看HashMap最常用的方法,如迭代、打印等。

3. TreeMap

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

classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
    publicboolean equals(Object o) {
        return((Dog) o).color == this.color;
    }
 
    publicint hashCode() {
        returncolor.length();
    }
    publicString toString(){   
        returncolor + " dog";
    }
}
 
publicclass TestTreeMap {
    publicstatic void main(String[] args) {
        Dog d1 = newDog("red");
        Dog d2 = newDog("black");
        Dog d3 = newDog("white");
        Dog d4 = newDog("white");
 
        TreeMap treeMap = newTreeMap();
        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接口。

classDog implementsComparable<Dog>{
    String color;
    intsize;
 
    Dog(String c, ints) {
        color = c;
        size = s;
    }
 
    publicString toString(){   
        returncolor + " dog";
    }
 
    @Override
    publicint compareTo(Dog o) {
        return o.size - this.size;
    }
}
 
publicclass TestTreeMap {
    publicstatic void main(String[] args) {
        Dog d1 = newDog("red",30);
        Dog d2 = newDog("black",20);
        Dog d3 = newDog("white",10);
        Dog d4 = newDog("white",10);
 
        TreeMap treeMap = newTreeMap();
        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 - 10
black dog - 15
white dog - 20

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

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

white dog - 20
red dog - 10
black dog - 15
white 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基础上增加的特性就是保存了插入对象的顺序。

classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
 
    publicboolean equals(Object o) {
        return((Dog) o).color == this.color;
    }
 
    publicint hashCode() {
        returncolor.length();
    }
 
    publicString toString(){   
        returncolor + " dog";
    }
}
 
publicclass TestHashMap {
    publicstatic void main(String[] args) {
 
        Dog d1 = newDog("red");
        Dog d2 = newDog("black");
        Dog d3 = newDog("white");
        Dog d4 = newDog("white");
 
        LinkedHashMap linkedHashMap = newLinkedHashMap();
        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 - 10
black dog - 15
white dog - 20

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

原文:http://www.importnew.com/8658.html Map是最重要的数据结构。这篇文章中,我会带你们看看HashMap, TreeMap, HashTable和LinkedH...
  • yin_jw
  • yin_jw
  • 2014年08月20日 16:43
  • 546

HashMap 、TreeMap、Hashtable、LinkedHashMap

HashMap通过一个哈希表实现,无序class Dog { String color; Dog(String c) { color = c; } pub...

常用键值对集合解析(HashMap,LinkedHashMap,TreeMap,HashTable,WeakHashMap,SparseArray,Array)

常用键值对集合解析(HashMap,LinkedHashMap,TreeMap,HashTable,WeakHashMap,SparseArray,Array)

HashMap、TreeMap、Hashtable、LinkedHashMap区别

HashMap 如果有重复的key,则将旧数据进行替换,允许设置key和value为null,key存放是乱序的,线程非同步,访问速度快,因为它根据key的HashCode 值来存储数据 public...

HashMap、LinkedHashMap、Hashtable和TreeMap用法和区别

Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap、HashTable、LinkedHashMap和TreeMap。本节实例主要介绍这4中实例的用...

HashMap TreeMap Hashtable LinkedHashMap 比较

1. Map 预览   4个都实现了Map 接口,用一句话为他们做简要的说明: HashMap 实现为一个哈希表,键或值没有顺序。 TreeMap 的是基于红黑树结构来实现,它是由键来排序的。 ...

JAVA HashMap,LinkedHashMap,TreeMap,HashTable 的区别

java中HashMap,LinkedHashMap,TreeMap,HashTable的区别 java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMa...
  • klov001
  • klov001
  • 2012年05月07日 20:39
  • 757

HashMap TreeMap Hashtable LinkedHashMap 区别

map是java中最常用的数据结构之一,在这篇文中,我将说明如何使用不同类型的maps,比如:HashMap,TreeMap,HashTable和LinkedHashMap。 Map概览 在jav...

java中HashMap,LinkedHashMap,TreeMap,HashTable,ConcurrentHashMap的区别和内部实现机制

首先简单介绍下,这几种map的应用场景: HashMap 存储键值对,没有什么特殊的功能; LinkedHashMap在存储的同时,能够保存用户插入数据的顺序,如果需要输出用户插入map的顺序可以...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap
举报原因:
原因补充:

(最多只允许输入30个字)