Map<K,V>接口及其子类HashMap的基本使用和其两种遍历方法(如何保证键为引用类型的唯一性)


接口 Map<K,V>

类型参数:
K - 此映射所维护的键的类型
V - 映射值的类型
public interface Map<K,V>
已知常用实现类: 
AbstractMap, EnumMap, HashMap, LinkedHashMap, TreeMap

将键映射到值的对象。
一个映射不能包含重复的键;
每个键最多只能映射一个值。 
通俗的说,键不可以重复,值可以重复(一个值可以被多个键映射)

Map接口和Collection接口的不同

	* Map是双列的,Collection是单列的
	* Map的键唯一,Collection的子体系Set是唯一的
	* Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

HashMap与HashSet的比较

他们的底层都是双列<K,V>存储的,只不过HashSet隐藏了一列v
底层都用哈希算法
 

Map集合的功能概述

* a:添加功能

		* V put(K key,V value):添加元素。
			* 如果键是第一次存储,就直接存储元素,返回null
			* 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

* b:删除功能

		* void clear():移除所有的键值对元素
		* V remove(Object key):根据键删除键值对元素,并把值返回

* c:判断功能

		* boolean containsKey(Object key):判断集合是否包含指定的键
		* boolean containsValue(Object value):判断集合是否包含指定的值
		* boolean isEmpty():判断集合是否为空

* d:获取功能

		* Set<Map.Entry<K,V>> entrySet():
		* V get(Object key):根据键获取值
		* Set<K> keySet():获取集合中所有键的集合
		* Collection<V> values():获取集合中所有值的集合

* e:长度功能

		* int size():返回集合中的键值对的个数


通过查看Map集合的api发现没有iterator方法,那么双列集合如何迭代呢?

	 * 根据键获取值


Map集合(HashMap)的遍历之键找值

键找值思路
 		获取所有键的集合
		遍历键的集合,获取到每一个键
		根据键找值


Map集合(HashMap)的第二种迭代,根据键值对对象,获取键和值

键值对对象找键和值思路:
		获取所有键值对对象的集合,把双列集合的键值对对象变成单列集合的键值对对象
		遍历这个键值对对象的集合,获取到每一个键值对对象
		根据键值对对象找键和值
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。该 set 受映射支持,
所以对映射的更改可在此 set 中反映出来,反之亦然。
如果对该 set 进行迭代的同时修改了映射
(通过迭代器自己的 remove 操作,或者通过对迭代器返回的映射项执行 setValue 操作除外),
则迭代结果是不确定的。
set 支持元素移除,通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作
可从映射中移除相应的映射关系。它不支持 add 或 addAll 操作。 
接口 Map.Entry<K,V>
正在封闭接口:Map<K,V> 
Entry<K,V>是Map<K,V>的内部接口
 K getKey() 
          返回与此项对应的键。 
 V getValue() 
          返回与此项对应的值。 


import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class a {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();//Map是一个接口,父类引用子类对象
		Integer i1 = map.put("张三", 23);
		Integer i2= map.put("李四", 24);
		Integer i3 = map.put("王五", 25);
		Integer i4 = map.put("赵六", 26);
		Integer i5 = map.put("张三", 26);//相同的键不存储,值覆盖,把被覆盖的值返回
		
		System.out.println(map);
		
		System.out.println(i1);
		System.out.println(i2);
		System.out.println(i3);
		System.out.println(i4);//null
		System.out.println(i5);//23

		System.out.println(map);//{李四=24, 张三=26, 王五=25, 赵六=26}
		Integer value = map.remove("张三");	//根据键删除元素,返回键对应的值
		System.out.println(value);//26
		System.out.println(map.containsKey("张三"));	//判断是否包含传入的键false
		System.out.println(map.containsValue(100));	//判断是否包含传入的值false
		System.out.println(map);//{李四=24, 王五=25, 赵六=26}
		
		
		Collection<Integer> c = map.values();
		System.out.println(c);//[24, 25, 26]
		System.out.println(map.size());//3
		
		
		Integer i = map.get("王五");	//根据键获取值
		System.out.println(i);//25
		
		//获取所有的键
		Set<String> keySet = map.keySet();	//获取所有键的集合
		Iterator<String> it = keySet.iterator();//获取迭代器
		while(it.hasNext()) {			//判断集合中是否有元素
			String key = it.next();		//获取每一个键
			Integer value1 = map.get(key);		//根据键获取值
			System.out.println(key + "=" + value);
		}
		/*李四=26
		王五=26
		赵六=26*/
		//使用增强for循环遍历
		for(String key : map.keySet()) { //map.keySet()是所有键的集合
			System.out.println(key + "=" + map.get(key));
		}
		
		
		//Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
		Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
		//获取每一个Entry对象
		Iterator<Map.Entry<String, Integer>> it1 = entrySet.iterator();
		while(it1.hasNext()) {
			//获取每一个Entry对象
			Map.Entry<String, Integer> en = it1.next();	//父类引用指向子类对象
			//Entry<String, Integer> en = it1.next();	//直接获取的是子类对象
			//查看HashMap中的Entry类
			System.out.print("en"+en);			//en李四=24en王五=25en赵六=26
			
			String key = en.getKey();			//根据键值对对象获取键
			Integer value3 = en.getValue();			//根据键值对对象获取值
			System.out.println(key + "=" + value3);
		}
		
		for(Entry<String, Integer> en : map.entrySet()) {
			System.out.println(en.getKey() + "=" + en.getValue());
		}

	}

}

interface inter{
	interface in{
		public void shoe();
	}
}
class Demo implements inter.in{
	@Override
	public void shoe() {
		// TODO Auto-generated method stub	
	}	
}

HashMap如何保证键为引用类型的唯一性


和hashset唯一性原理一样
需重写student中的equals和hashcode方法
HashMap的父类 重写了tostring方法

import java.util.HashMap;
import bean.Student;
/**
HashMap集合键是Student值是String的案例
HashMap如何保证键为引用类型的唯一性
 */
public class b {

	public static void main(String[] args) {
		HashMap<Student, String> hm = new HashMap<>();
		hm.put(new Student("张三", 23), "北京");
		hm.put(new Student("张三", 23), "上海");
		hm.put(new Student("李四", 24), "广州");
		hm.put(new Student("王五", 25), "深圳");
		
		System.out.println(hm);
		
	}

}

附上student类

package bean;

public class Student implements Comparable<Student> {
	
	String name;
	int age;
	
	public Student() {
		super();
		
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
		
} 





  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值