HashMap,Hashtable,TreeMap,LinkedHashMap 比较

先来看一下这几个map的关系图

HashMap,Hashtable,TreeMap,LinkedHashMap 比较











可以看出,Hashtable,HashMap,TreeMap,LinkedHashMap 都是实现与Map借口。不同的是TreeMap实现于 SortedMap,这个就决定了TreeMap存储的数据是可以排序的。

下面用四句话来概括这四个map的用法

1.Hashtable 是安全的(synchronized)
2.LinkedHashMap  保留插入顺序
3.TreeMap 是基于红黑树的数据结构,他的键是有序的
4.HashMap 的键是无序


二 代码

  HashMap  用自定义的对象做为键

import java.util.HashMap;
import java.util.Map.Entry;

public class HashMapTest{

  public static void main(String[] args){
    HashMap<Person,Integer> hashMap = new HashMap<Person,Integer>();
    Person p1 = new Person("Rookie",10);
    Person p2 = new Person("BruceChen",20);
    Person p3 = new Person("HackerRookie", 30);
    Person p4 = new Person("HackerRookie", 30);
    
    hashMap.put(p1,10);
    hashMap.put(p2,20);
    hashMap.put(p3,30);
    hashMap.put(p4,30);

    System.out.println(hashMap.size());
    for(Entry entry : hashMap.entrySet()){
      System.out.println(entry.getKey().toString() + " - " + entry.getValue());
    }
  }

}


class Person{
  String name ;
  int    age  ;
  
  public Person(String name,int age){
     this.name = name;
     this.age  = age;
  }

  public String toString(){
     return name + " 年龄 " + age;
  }
}

  Output:

4
BruceChen 年龄 20 - 20
Rookie 年龄 10 - 10
HackerRookie 年龄 30 - 30
HackerRookie 年龄 30 - 30

   上面的测试类,有一个问题,重复的添加了两个相同的人,HashMap并没有过滤。
   要想过滤掉重复的值,需要重写Object对象的 equals() 和hashCode()

 

class Person{
  String name ;
  int    age  ;
  
  public Person(String name,int age){
     this.name = name;
     this.age  = age;
  }

  public String toString(){
     return name + " 年龄 " + age;
  }
  
  public boolean equals(Object o){
    Person p = (Person)o;
    if(p.name.equals(this.name) && p.age == this.age){
       return true;
    }
    
    return (Person)o == this;
  }
  
  public int hashCode(){
    return this.name.length();
  }
}

  Output:
   

3
Rookie 年龄 10 - 10
BruceChen 年龄 20 - 20
HackerRookie 年龄 30 - 30

  3. TreeMap

  TreeMap的排序是以键来排序的,我们以自定义对象为键来说明

 

mport java.util.TreeMap;
import java.util.Map.Entry;

public class TreeMapTest{

  public static void main(String[] args){
    TreeMap<Duck,Integer> tM = new TreeMap<Duck,Integer>();
    
    Duck d1 = new Duck("white",30);
    Duck d2 = new Duck("green",10);
    Duck d3 = new Duck("black",54);
    
    tM.put(d1, 10);
    tM.put(d2,30);
    tM.put(d3, 40);
    
    System.out.println(tM.size());
    
    for(Entry entry : tM.entrySet()){
      System.out.println(entry.getKey() + " - " + entry.getValue());
    }
  }
}

class Duck{
  String color;
  int size;
  
  public Duck(String color,int size){
    this.color = color;
    this.size = size;
  }
  
  public boolean equals(Object o){
    return ((Duck)o).color == this.color;
  }
  
  public int hashCode(){
    return this.color.length();
  }

  public String toString(){
    return this.color + " Duck";
  }
  
}

  Output:(这里抛出异常信息)

Exception in thread "main" java.lang.ClassCastException: com.breeze.test.Duck 
cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(Unknown Source)
    at com.breeze.test.TreeMapTest.main(TreeMapTest.java:16)

   因为TreeMap是以key来来排序的,而我们的Duck对象并没有相互比较的能力.在java中,要想实现比较,必须实现Comparable 借口.在TreeMap中之所以可以用string来做key,就是因为 string实现了comparable借口,现在来修改Duck对象

mport java.util.TreeMap;
import java.util.Map.Entry;

public class TreeMapTest{

  public static void main(String[] args){
    TreeMap<Duck,Integer> tM = new TreeMap<Duck,Integer>();
    
    Duck d1 = new Duck("white",30);
    Duck d2 = new Duck("green",10);
    Duck d3 = new Duck("black",54);
    
    tM.put(d1, 10);
    tM.put(d2,30);
    tM.put(d3, 40);
    
    System.out.println(tM.size());
    
    for(Entry entry : tM.entrySet()){
      System.out.println(entry.getKey() + " - " + entry.getValue());
    }
  }
}

class Duck implements Comparable<Duck>{
  String color;
  int size;
  
  public Duck(String color,int size){
    this.color = color;
    this.size = size;
  }
  
  public boolean equals(Object o){
    return ((Duck)o).color == this.color;
  }
  
  public int hashCode(){
    return this.color.length();
  }

  public String toString(){
    return this.color + " Duck";
  }
  
  @Override
  public int compareTo(Duck d){
    return d.size - this.size;
  }
  
  
}

 Output:

 

3
black Duck - 40
white Duck - 10
green Duck - 30

3.Hasthtable 和 HashMap如出一辙,不同的是,HashMap的值是可以为null的,也不是synchroized

4。LinkedHashMap 继承自HashMap,它使插入linked里的数据,保留插入时的顺序。

你可能感兴趣的:(HashMap,Hashtable,TreeMap,LinkedHashMap 比较)