Java类集学习(四)Map接口

之前说的Set(HashSet、TreeSet)接口和List(ArrayList、Vector、LinkedList)接口都是对单值别的操作,即每次只能操作一个对象。

Map接口与他们不同的是每次操作一对对象,Map中每个元素都使用“key----->value”的形式存储在集合中。

public interface Map<K,V>

1、Map.Entry接口

Map.Entry接口是Map内部定义的一个接口,专门用来保存key--->Value的内容,是static关键字声明的内部接口。

public static interface Map.Entry<K,V>

我们知道,在Map接口的操作中,所用的内容都是通过key--->Value的形式保存数据的,那么对于集合来讲,实际上将“key---->value”的数据保存在了Map.Entry接口的实例后,再在Map集合中插入一个Map.Entry的实例化对象,如下图所示:


一般在Map操作中(增加、取出数据)用户不用关心Map.Entry,但是将Map中的数据全部输出时必须使用Map.Entry,随后介绍。

本节主要介绍常用的子类:

HashMap:无序存放,新的操作类,key不允许重复。

HashTable:无序存放,旧的操作类,key不允许重复。

TreeMap:可排序map集合,按集合中key排序,key不允许重复。

WeakHashMap:弱引用Map集合,集合中某些内容不再使用时清除,使用gc回收。

IndentityHashMap:key可以重复的map集合。

2、HashMap

(1)向集合中增加和取出内容

          put(K key, V value);增加

          get(Object K)根据key找到对应的内容value

public class HashMapDemo01 {
	/**
	 * Map接口中使用put增加内容,使用get(Object Key)根据Key找到内容value
	 */
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "www.bupt.cn");
		map.put("2", "www.baidu.cn");
		map.put("3", "www.haha.cn");
		String str = map.get("1");
        System.out.println("取得的内容是:"+str);
	}
}

输出结果为:

取得的内容是:www.bupt.cn
(2)判断指定的key或value是否存在

          contains(Object key);

          contains(Object value);

public class HashMapDemo06 {
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "www.bupt.cn");
		map.put("2", "www.baidu.com");
		map.put("3", "www.haha.com");
		if(map.containsKey("2")){
			System.out.println("搜索的key存在");
		}else{
			System.out.println("搜索的key不存在");
		}
		if(map.containsValue("www.souhu.com")){
			System.out.println("搜索的value存在");
		}else{
			System.out.println("搜索的value不存在");
		}
	}
}
输出结果:

指定的key存在
指定的value不存在

(3)输出全部的key

          Map接口中提供了一个keySet()的方法,可以将一个Map中的全部key变成一个Set集合,一旦有了Set接口实例,就可以直接使用Iterator接口进行输出。操作时注意接收的Set集合中指定的泛型要和Map中key的泛型类型一致。

public class HashMapDemo02 {
	/**
	 * 输出全部的Key
	 */
	public static void main(String[] args) {
	Map<String,String> map = new HashMap<String,String>();
        map.put("1","www.bupt.cn");
        map.put("2", "www.baidu.cn");
        map.put("3", "www.haha.cn");
        Set<String> keys = map.keySet();//得到全部的Key,放入set集合
        Iterator<String> iter = keys.iterator();//实例化Iterator
        System.out.print("全部的Key:");
        while(iter.hasNext()){
        	String str = iter.next();
        	System.out.print(str+"、");
        }
	}
}

输出结果:

全部的Key:1、2、3、

(4)输出全部的value

         使用values()方法,返回Collection类型。使用时同样注意泛型的类型。

public class HashMapDemo03 {
	/**
	 * 输出全部的value
	 */
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "www.bupt.cn");
		map.put("2", "www.baidu.com");
		map.put("3", "www.haha.com");
		Collection<String> coll = map.values();//得到全部的value,放入Collection
		Iterator<String> iter = coll.iterator();//实例化Iterator
		System.out.print("全部的value:");
		while(iter.hasNext()){
			String str = iter.next();
			System.out.print(str+"、");
		}
	}
}
输出结果:

全部的value:www.bupt.cn、www.baidu.com、www.haha.com、

2、HashTable

HashTable与vector类的推出时间一样,都属于旧的操作类,使用上没有太大区别。

性能:HashMap异步处理,性能高;HashTable同步处理,性能低。

线程安全:HashMap非线程安全;HashTable线程安全。

空键:允许Key设置为null;HashTable不允许将Key设置为null,否则出现Null Pointer Exception异常

实际开发中HashMap类使用较多。

3、TreeMap

之前的HashMap、HashTable存放数据时并没有对其进行排序。

TreeMap子类的主要特点:可以按Key排序。(数字、字母等)

注意:使用自定义类作为key时,类需要实现Comparable接口,String类作为key可以按key排序,因为String类本身已经实现了Comparable接口。

4、IdentityHashMap:key可以重复的Map集合

以上介绍的Map操作中key的值是不能重复的,例如,HashMap操作时如果key重复则肯定会覆盖之前的内容。

下面结合实例主要看一下Map集合输出全部内容以及IdentityHashMap的使用

这里的Key为一个自己定义的类Person2

class Person2 implements Serializable{
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	public Person2(){}
	public Person2(String name, int age){
		this.name = name;
		this.age = age;
	}
// 重写equals,定义同一类型,并且属性name和age全部相等则实例对象相等 
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}
		if(!(obj instanceof Person2)){
			return false;
		}
		Person2 p = (Person2) obj;
		if(this.name.equals(p.name)&&this.age == p.age){
			return true;
		}else{
			return false;
		}
	}
//  重写HashCode将对象的某些信息映射成一个数值---散列值  
	public int hashCode(){
		return this.name.hashCode()*this.age;//计算公式
	}
// 重写toString打印自己想要的格式,如果不重写默认直接继承Object类的toString 方法是获取对象在内存中的值可能会乱码 
	public String toString(){
		return "姓名:"+this.name+";年龄:"+this.age;
	}
}

public class IdentityHashMapDemo {
/**
 * key 可以重复的IdentityHashMap类
 */
	public static void main(String[] args) {
		Map<Person2,String> map = new IdentityHashMap<Person2,String>(); 
		map.put(new Person2("张三",30), "张三1");
		map.put(new Person2("张三",30), "张三2");//增加内容,key重复
		map.put(new Person2("李四",31), "李四");
//		输出map集合全部内容:
//		声明Set集合(存单值),每个内容都是Map.Entry的对象,Map接口通过entrySet()变为set接口对象
		Set<Map.Entry<Person2,String>> allSet = map.entrySet();
//		声明并实例化Iterator对象
		Iterator<Map.Entry<Person2,String>> iter = allSet.iterator();
//		迭代输出
		while(iter.hasNext()){
			Map.Entry<Person2, String> m = iter.next();//每个对象都是Map.Entry实例
			System.out.println(m.getKey()+"---->"+m.getValue());
		}
	}
}
输出结果:

姓名:张三;年龄:30---->张三1
姓名:李四;年龄:31---->李四
姓名:张三;年龄:30---->张三2

由此可见IdentityHashMap中key允许重复,只要两个对象的地址不相等即可。

5、Map接口使用需要注意的事项:

a、输出Map全部内容的方法,先转为Set接口对象,再利用Set对象实例化Iterator,利用Iterator输出每一个内容Map.Entry的对象


b、如果使用一个自定义的对象类表示Map中的key,则对象所在的类一定要重写equals()和HashCode()方法。

发布了36 篇原创文章 · 获赞 4 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章