JavaSE入门学习37:Java集合框架之Map接口及其实现类HashMap和TreeMap

        一Map接口

        Map接口中的每个成员方法由一个关键字(key)和一个值(value)构成。Map接口不直接继承于Collection接口,因

为它包装的是一组成对的"键-值"对象的集合,而且在Map接口的集合中也不能有重复的key出现,因为每个键只能与

一个成员元素相对应。

        Map接口定义了存储"键(key)——值(value)映射对"的方法。实现Map接口的类用来存储键值对。Map接口中包含

了一个keySet()方法,用于返回Map中所有key组成的Set集合。

        Map接口的特点有: 

        1)Map接口提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储 的,能够实现根据key快速查找value。

        2)Map中的键值对以Entry类型的对象实例形式存在。键(key值)不可重复,value值可以。

        3)每个键最多只能映射到一个值。

        4)Map接口提供了分别返回key值集合,value值集合以及Entry(键值对)集合的方法。

        5)Map同样也支持泛型,形式如:Map<K,V>。

        6)Map接口中存储的键—值对通过键来标识,所以键值不能重复,即同一个Map对象的任何两个key通过equals()

方法比较总是返回false。

       Map接口中定义的方法有:


       Map接口的主要有三个实现类,分别是:HashMap、TreeMap和HashTable。一般情况下,我们用的最多的是

HashMap,在Map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历

键,那么TreeMap会更好。如果需要输出的顺序和输入的相同。那么用HashMap的子类LinkedHashMap可以实现,

它还可以按读取顺序来排列。

        二HashMap实现类

        Hashmap类是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访

速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为

 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要

同步,可以用Collections集合类的synchronizedMap()方法使HashMap类具有同步的能力。

        由于HashMap里的不能重复,所以HashMap里最多只有一对key-value值为null,但可以有无数多项key-value对

的value为null。

  HashMap重写了toString()方法方法总是返回如下格式的字符串:{key1 = value1,key2 = value2...}

  HashMap判断两个key相等的标准是:两个key通过equasl()方法比较返回ture,两个key的hashCode值相等。

       HashMap的特点:

       1)HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现。

       2)HashMap中的Entry对象是无序排列的。

       3)Key值和value值都可以是null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)。

       HashMap实现类的方法:


       实例:

import java.util.*;

public class TestHashMap {
	public static void main(String[] args) {
		Map<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 (Map.Entry<Dog, Integer> entry : hashMap.entrySet()) {
			System.out.println(entry.getKey().toString() + " - " + entry.getValue());
		}
	}
}

class Dog {
	String color;
 
	Dog(String c) {
		color = c;
	}
	
	public String toString(){	
		return color + " dog";
	}
}

      运行结果:


      注意看,我们错误地添加了两次"white dogs",但是HashMap接受了,这严格来说是没意义的,因为现在对"white 

dogs"的数量产生了混淆。

      修正后的 Dog 类如下所示:

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

      运行结果:


      原因在于HashMap不运行两个相同的元素作为KEY。如果没有重写,使用的就会是Object类实现的hashCode()和

equals()方法,默认的 hashCode()方法实现对每个不同的对象返回不同的整数;默认的equals()方法只比较两个引用

是否指向同一个实际对象。

      三TreeMap实现类

      Map接口派生了一个SortedMap子接口,TreeMap为其实现类。类似TreeSet排序,TreeMap也是基于红黑树对

TreeMap中所有key进行排序,从而保证TreeMap中所有key-value对处于有序状态。TreeMap两种排序方法:

       1)自然排序:TreeMap的所有key必须实现Comparable接口,而且所有key应该是同一个类的对象,否则将会抛出

ClassCastExcepiton异常。

       2)定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中所有key进行排序。采用定

制排序时不要求Map的key实现Comparable接口。

  TreeMap中判断两个key相等的标准也是两个key通过equals()方法比较返回true,而通过compareTo()方法返回

0,TreeMap即认为这两个key是相等的。

  如果使用自定义的类作为TreeMap的key,应重新该类的equals(0方法和compareTo()方法时应有一致的返回结

果:即两个key通过equals()方法比较返回true时,它们通过compareTo()方法比较应该返回0。如果equals()方法与

compareTo()方法的返回结果不一致,要么该TreeMap与Map接口的规则有出入(当equals()方法比较返回true,但

CompareTo()方法比较不返回0时),要么TreeMap处理起来性能有所下降(当compareTo()方法比较返回0,当

equals()方法比较不返回true时)。

         TreeMap实现了的方法:




        实例:

import java.util.*;

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");
 
		Map<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
		treeMap.put(d1, 10);
		treeMap.put(d2, 15);
		treeMap.put(d3, 5);
		treeMap.put(d4, 20);
 
		for (Map.Entry<Dog, Integer> entry : treeMap.entrySet()) {
			System.out.println(entry.getKey() + " - " + entry.getValue());
		}
	}
}

class Dog {
	String color;
 
	Dog(String c) {
		color = c;
	}

	public boolean equals(Object o) {
		return ((Dog) o).color == this.color;
	}
 
	public int hashCode() {
		return color.length();
	}

	public String toString(){	
		return color + " dog";
	}
}

        运行结果:


       既然TreeMap是按key排序的,那么key对象就必须可以和另一个对象作比较,因此必须实现Comparable接口。当

然,你也可以使用String对象作为key,因为String类已经实现了Comparable接口。

       下面,我们修改Dog类的代码,使其实现Comparable接口:

import java.util.*;

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);
 
		Map<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
		treeMap.put(d1, 10);
		treeMap.put(d2, 15);
		treeMap.put(d3, 5);
		treeMap.put(d4, 20);
 
		for (Map.Entry<Dog, Integer> entry : treeMap.entrySet()) {
			System.out.println(entry.getKey() + " - " + entry.getValue());
		}
	}
}

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;
	}
}

       运行结果:


       这就是根据key对象排序的结果,此处我们使用了size(尺寸)来比较dog.如果我们把"Dog d4 = new Dog("white"

,10);"这一行代码替换为"Dog d4 = new Dog("white", 40);"那么,执行后的结果为:


       原因是TreeMap使用compareTo()方法来比较key对象,不同的size就被认为是不同的dog。

       关于Map接口及其实现类的东西就说这么多。

      

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值