Java中的HashMap ,TreeMap ,Hashtable ,LinkedHashMap 之间的比较

Map是Java中最重要的数据结构之一。在本文中,我将说明如何使用不同类型的地图,例如HashMap,TreeMap,HashTable和LinkedHashMap。

1.地图概述
在这里插入图片描述
Java SE中有4种常用的Map实现-HashMap,TreeMap,Hashtable和LinkedHashMap。如果我们仅使用一个句子来描述每个实现,则将是以下内容:
1,HashMap被实现为哈希表,并且键或值没有排序。
2,TreeMap是基于红黑树结构实现的,并通过密钥进行排序。
3,LinkedHashMap保留插入顺序
4,与HashMap相比,Hashtable是同步的。同步有开销。
这就是如果程序是线程安全的,则应使用HashMap的原因。

2. HashMap
如果HashMap的键是一个自定义对象,则需要遵循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<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
black dog - 15
red dog - 10
white dog - 20

注意这里,我们错误地两次添加了“白狗”,但是HashMap接受了它。这没有道理,因为现在我们对真正有多少只白狗感到困惑。

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最常用的方法,例如迭代,打印等。

3. TreeMap

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 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<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: 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接口。

让我们换一下狗,使其具有可比性。

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 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<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 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()方法比较键。不同的大小使不同的狗!

4.哈希表

根据Java Doc:
HashMap类与Hashtable大致等效,但它是不同步的,并且允许为null。

5. LinkedHashMap

LinkedHashMap是HashMap的子类。这意味着它继承了HashMap的功能。此外,链表保留插入顺序。

让我们使用与HashMap相同的代码将HashMap替换为LinkedHashMap。

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 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<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
发布了0 篇原创文章 · 获赞 0 · 访问量 89

猜你喜欢

转载自blog.csdn.net/qq_41806546/article/details/105137274