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接口及其实现类的东西就说这么多。

时间: 2025-01-15 12:07:09

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

Java集合框架中Map接口的使用

在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不是线性的存放对象的引用,Map接口提供了一种映射关系,所有的元素都是以键值对(Entry类型对象实例)的方式存储的,所以能够根据key快速查找value,key是映射关系的索引,value是key所指向的对象,注意,这里的value不是一个数值,而是一个对象的引用,Java集合框架的元素均是指对象!

JavaSE入门学习35:Java集合框架之List接口及其实现类ArrayList和LinkedList

一List接口概述 List接口是Collection接口的子接口,实现List接口的集合类中的元素是有顺序的,而且可以重复,被称为序列. List集合中的元素都对应一个整数型的序列容器中的序号记载其在容器中的位置,可以根据序号存取容器中的元 素.List接口可以精确的控制每个元素的插入位置,或者删除某个位置元素. Java所提供的List集合实现类类有ArrayList实现类.LinkedList实现类.Vector等,我们主要使用的是ArrayList实 现类和LinkedList实现类.

I学霸官方免费教程三十五:Java集合框架之Collection接口和Collections类

Collection接口 Collection接口是List和Set接口的父接口,其中主要定义了一些集合基本操作的方法,包括与Iterator之间的关系List  extends  CollectionArrayList  implements  ListLinkedList  implements  ListVector  implements  ListSet  extends  CollectionHashSet  implements  SetSortedSet  extends  Se

JavaSE入门学习36:Java集合框架之Set接口及其实现类HashSet和TreeSet

一Set接口 Set接口可以与数学中的集合的概念相对应.Set接口是Collection接口的子接口,Set接口里多个对象之间没有明 显的顺序.具体详细方法请参考API文档(可见身边随时带上API文档有多重要),基本与Collection接口中定义的方法相 同.只是行为不同(Set不允许包含重复元素). Set集合不允许重复元素,是因为Set判断两个对象相同不是使用==运算符,而是根据equals()方法.即两个对象 用equals()方法比较返回true,Set就不能接受两个相等的对象. 我们

Java集合框架总结(3)——TreeSet类的排序问题

Java集合框架总结(3)--TreeSet类的排序问题 TreeSet支持两种排序方法:自然排序和定制排序.TreeSet默认采用自然排序. 1.自然排序 TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式就是自然排序.(比较的前提:两个对象的类型相同). java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该

java集合框架小结(进阶版)之HashMap篇

基本概念: Hash(哈希):hash一般也译作“散列”.事实上,就是一个函数,用于直接定址.将数据元素的关键字key作为变量,通过哈希函数,计算生成该元素的存储地址. 冲突:函数是可以多对一的.即:多个自变量可以映射到同一函数值.一般而言,不同的key的hash值是不同的.在往hash表中映射的时候,不同的hash值可能映射到同一存储地址,这种情况被称为冲突. 解决冲突的方法: 1. 链表法:将冲突的各个元素用一个一维数组来维护.(java源码实现) 2. 开发寻址法:具体的有线性探测法.二次

Java集合框架之List接口

在上一篇Java集合框架之Collection接口中我们知道List接口是Collection接口的子接口,List接口对Collection进行了简单的扩充,List接口中的元素的特点为有序,可重复,允许null值,因为List继承了Collection接口,所以继承自Collection接口中的方法不再赘述,从List接口中的方法来看,List接口主要是增加了面向位置的操作,允许在指定位置上对集合中的元素进行操作,同时增加了一个能够双向遍历线性表的新列表迭代器ListIterator.下面介

Java集合框架中List接口的简单使用

Java集合框架可以简单的理解为一种放置对象的容器,和数学中的集合概念类似,Java中的集合可以存放一系列对象的引用,也可以看做是数组的提升,Java集合类是一种工具类,只有相同类型的对象引用才可以放到同一个集合中,否则是不能放进去的: 集合可以对元素进行简单快速的查找.插入.删除操作 某些集合可以有<key value>映射的关系 数组的长度是固定的,而集合的长度是跟随元素的个数动态变化的,灵活性和扩展性都比数组更加优越 数组只能存放基本类型的数据,而集合存放的是对象引用类型的 数组只能通过

【JAVA集合框架之Map】

一.概述.1.Map是一种接口,在JAVA集合框架中是一个非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map集合中存放的是一个一个的键值对,集合中存放的元素必须保证键的唯一性.二.常用方法.1.添加  V put(K key, V value)           将指定的值与此映射中的指定键关联(可选操作). 该方法的作用就是向集合中添加一个键值对,并返回一个值:如果键存在,则返回对应的旧值,并以新值取代