Map是一个重要的数据结构,本篇文章将介绍如何使用不同的Map,如HashMap,TreeMap,HashTable和LinkedHashMap。

Map概览

Java中有四种常见的Map实现,HashMap,TreeMap,HashTable和LinkedHashMap,我们可以使用一句话来描述各个Map,如下:

  • HashMap:基于散列表实现,是无序的;
  • TreeMap:基于红黑树实现,按Key排序;
  • LinkedHashMap:保存了插入顺序;
  • Hashtable:是同步的,与HashMap类似;

HashMap

如果HashMap的Key是自己定义的对象,那么一般需要覆盖equals()和hashCode()方法,且要遵循他们之间的约定。

package simplejava;

import java.util.HashMap;
import java.util.Map.Entry; class Dog {
String color; Dog(String c) {
color = c;
} public String toString() {
return color + " dog";
}
} public class Q26 { public static void main(String[] args) {
HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();
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 size
System.out.println(hashMap.size());
//loop HashMap
for (Entry<Dog, Integer> entry : hashMap.entrySet()) {
System.out.println(entry.getKey().toString() + " - " +
entry.getValue());
}
} }

结果输出:

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

注意,我们不小心添加了两个"white dogs“,但是HashMap仍然存储它。这是不合理的,现在我们困惑到底有多少条白狗存入了HashMap,5还是20呢。

其实,Dog类应该是这样定义的:

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

结果输出:

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

原因是因为HashMap不允许两个相同的元素存入,默认情况下,Object的hashCode()和equals()会被用于判断两个对象是否相同。默认的hashCode()方法对于不同的对象会返回不同的值,而equals()方法只有当两个引用相等,即指向同一个对象的时候才返回true。如果你不是很清楚,可以自己检验下hashCode()和equals()之间的关系。

举个例子,可以检验下HashMap中最常用的方法,如iteration,print等。

TreeMap

TreeMap是按key排序的,让我们先看下如下代码,了解其“按key排序”思想。

package simplejava;

import java.util.Map.Entry;
import java.util.TreeMap; class Dog {
String color; Dog(String c) {
color = c;
} public boolean equals(Object o) {
return ((Dog) o).color.equals(this.color);
} public int hashCode() {
return color.length();
} public String toString() {
return color + " dog";
}
} public class Q26 { 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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20); for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
} }

结果输出:

Exception in thread "main" java.lang.ClassCastException: simplejava.Dog cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1188)
    at java.util.TreeMap.put(TreeMap.java:531)
    at simplejava.Q26.main(Q26.java:34)

由于TreeSet是基于Key排序的,所以作为key的对象需要相互比较,这就是为什么key需要实现Comparable接口。举个例子,你可以使用字符串作为Key,因为String已经实现了Comparable接口。

现在,让我们改变一下Dog,让它可比较,如下:

package simplejava;

import java.util.Map.Entry;
import java.util.TreeMap; class Dog implements Comparable<Dog> {
String color;
int size; Dog(String c, int s) {
color = c;
size = s;
} public String toString() {
return color + " dog";
} @Override
public int compareTo(Dog o) {
return o.size - this.size;
}
} public class Q26 { 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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
treeMap.put(d1, 10);
treeMap.put(d2, 15);
treeMap.put(d3, 5);
treeMap.put(d4, 20);
for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
} }

结果打印:

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

在这个例子中,我们是按dog的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()去比较key,不同的size意味着不同的dogs。

HashTable

参考java文档:HashMap与HashTable基本类似,除了非同步和允许null外。

LinkedHashMap

LinkedHashMap是HashMap的子类,意味着它继承了HashMap的特性,除此之外,LinkedHashMap还保存了插入顺序。

让我们使用同样的代码,然后将HashMap替换成LinkedHashMap,如下:

package simplejava;

import java.util.LinkedHashMap;
import java.util.Map.Entry; class Dog {
String color; Dog(String c) {
color = c;
} public boolean equals(Object o) {
return ((Dog) o).color.equals(this.color);
} public int hashCode() {
return color.length();
} public String toString() {
return color + " dog";
}
} public class Q26 { 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<Dog, Integer> linkedHashMap = new LinkedHashMap<Dog, Integer>();
linkedHashMap.put(d1, 10);
linkedHashMap.put(d2, 15);
linkedHashMap.put(d3, 5);
linkedHashMap.put(d4, 20);
for (Entry<Dog, Integer> 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

更多阅读:ArrayList vs. LinkedList vs. Vector

译文链接:http://www.programcreek.com/2013/03/hashmap-vs-treemap-vs-hashtable-vs-linkedhashmap/

HashMap vs TreeMap vs Hashtable vs LinkedHashMap的更多相关文章

  1. 【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别

    转自:http://blog.csdn.net/paincupid/article/details/47746341 一.HashMap和TreeMap区别 1.HashMap是基于散列表实现的,时间 ...

  2. [Java] HashMap、TreeMap、Hashtable排序

    Java中对Map(HashMap,TreeMap,Hashtable等)的排序时间 首先简单说一下他们之间的区别: HashMap: 最常用的Map,它根据键的HashCode 值存储数据,根据键可 ...

  3. Java 容器 & 泛型:五、HashMap 和 TreeMap的自白

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Java 容器的文章这次应该是最后一篇了:Java 容器 系列. 今天泥瓦匠聊下 Maps. 一.Ma ...

  4. HashMap、HashTable、LinkedHashMap和TreeMap用法和区别

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

  5. Android——ArrayList 、LinkList、List 区别 & 迭代器iterator的使用 & HashMap、Hashtable、LinkedHashMap、TreeMap

     ArrayList .LinkList.List 区别 & 迭代器iterator的使用 & HashMap.Hashtable.LinkedHashMap.TreeMap 一.几个 ...

  6. Java集合系列(四):HashMap、Hashtable、LinkedHashMap、TreeMap的使用方法及区别

    本篇博客主要讲解Map接口的4个实现类HashMap.Hashtable.LinkedHashMap.TreeMap的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 ...

  7. hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法区别详解

    Java集合中设计了一个接口Java.util.Map,它实现类中hashMap.hashTable.TreeMap.ConcurrentHashMap.LinkedHashMap. Map类型的集合 ...

  8. 【Java】Map杂谈,hashcode()、equals()、HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap

    参考的优秀文章: <Java编程思想>第四版 <Effective Java>第二版 Map接口是映射表的结构,维护键对象与值对象的对应关系,称键值对. > hashco ...

  9. HashMap相关类:Hashtable、LinkHashMap、TreeMap

    前言 很高兴遇见你~ 在 深入剖析HashMap 文章中我从散列表的角度解析了HashMap,在 深入解析ConcurrentHashMap:感受并发编程智慧 解析了ConcurrentHashMap ...

随机推荐

  1. 关于JQuery

    整理jq基础常用(过于基础别喷): 1, $('div input[name]').css('','');//获取层中有name属性的标签 $('div input[name=txtname]').c ...

  2. 介绍开源的.net通信框架NetworkComms框架 源码分析(十七 ) ConnectionSendClose

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  3. C#中使用Sql对Excel条件查询

    如何在C#中实现对Excel的条件查询呢? 在使用Sql条件语句对Excel进行查询时,遇到"至少一个参数没有被指定值"的问题,如何解决? 使用OleDbConnection对象创 ...

  4. Python 3 利用 subprocess 实现管道( pipe )交互操作读/写通信

    这里我们用Windows下的shell来举例: from subprocess import * #因为是举例,就全部导入了 为了方便你理解,我们用一个很简单的一段代码来说明: 可以看见我们利用Pop ...

  5. 2015暑假多校联合---Assignment(优先队列)

    原题链接 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbere ...

  6. 2016暑假多校联合---To My Girlfriend

    2016暑假多校联合---To My Girlfriend Problem Description Dear Guo I never forget the moment I met with you. ...

  7. Scalaz(45)- concurrency :Task-函数式多线程编程核心配件

    我们在上一节讨论了scalaz Future,我们说它是一个不完善的类型,最起码没有完整的异常处理机制,只能用在构建类库之类的内部环境.如果scalaz在Future类定义中增加异常处理工具的话,用户 ...

  8. [moka同学笔记]Yii2中多表关联查询(join、joinwith) (摘录)

    表结构 现在有客户表.订单表.图书表.作者表, 客户表Customer   (id  customer_name) 订单表Order          (id  order_name       cu ...

  9. mongodb数据库备份导入导出数据

    备份数据: mongodump -h 192.168.2.20 -u game -p 12345678 -d dbname -o /data/test/ --excludeCollection=use ...

  10. 【局部特征】ASIFT

    由于相机正面白摄物体时,相机的光轴方向可能发生变化,带来扭曲.而SIFT算法虽具有完全的尺度不变性,但不具有完全的仿射不变性,对拍摄角度发生大角度空间变化的图像特征提取有一定的局限性.ASift通过模 ...