Java中Map集合的使用

Java中Map集合的使用

Map接口

1.概述:

Map集合为映射类型(一一对应的关系),即集合中的每个对象都是成对存在的。映射中存储的每个对象都有一个相应的键(key)对象,在检索时,必须通过相应的键对象来获取值(value)对象,这个操作类似于在字典中查找单词,所以要求键对象必须是唯一的

2.与Collection的区别:

1.Collection中的集合,元素是孤立存在的(可看作单身汉),向集合中存储元素时采用每次只存储一个元素的方式。
2.Map中的集合,元素是成对存在的(可看作夫妻)。每个元素由键与值两部分组成,通过建可以找到所对应的值。
3.Collection中的集合称为单列集合,Map中的集合称为双列集合。

在这里插入图片描述

3.Map接口常用方法:
修饰语和类型 方法 描述
V put(K key, V value) 将指定的值与此映射中的指定键关联
V get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回null

这里的K指作为键(key)的对象,V指作为值(values)的对象。

注意:这里V put(K key, V value)方法的返回值为V,通常情况下,如果打印这个返回值,那么内容都将为null。但当存储的是重复的键(key)时,不会出现重建现象,而是将原先这个键所对应的值覆盖掉,这时再接收并打印这个返回值时,内容为被覆盖掉的那个值对象。

修饰语和类型 方法 描述
Set keySet() 返回此映射中包含的键的Set视图

顾名思义,此方法是将Map集合中的所有键单独存储到一个Set集合中去。由于Map集合中的键值对应关系(就像二次函数中x与y的对应关系),所以得到键后,通过遍历这个Set集合,自然可以得到值。我们可以通过这种方式对Map集合进行遍历。

示例代码:

public class MapDemo1 {
   
	public static void main(String[] args) {
   
		/* * 1.调用map集合的方法keySet,将所有的键存储到Set集合中 * 2.遍历Set集合,获取出Set集合中的所有元素 (Map中的键) * 3.调用map集合方法get,通过键获取到值 */
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("a", 1);
		map.put("b", 2);
		map.put("c", 3);
		map.put("d", 4);

		// 调用map集合的方法keySet,所有的键存储到Set集合中
		Set<String> set = map.keySet();
		// 遍历Set集合,获取出Set集合中的所有元素 (Map中的键)
		Iterator<String> it = set.iterator();
		while (it.hasNext()) {
   
			// it.next返回是Set集合元素,也就是Map中的键
			// 调用map集合方法get,通过键获取到值
			String key = it.next();
			Integer value = map.get(key);
			System.out.println(key + ":" + value);
		}
		
		System.out.println("以增强for的方式遍历:");
		
		for (String key : map.keySet()) {
   
			Integer value = map.get(key);
			System.out.println(key + ":" + value);
		}
	}
}

注意:打印集合元素的顺序不按照存储的顺序。

Entry键值对对象:

在Map类设计时,提供了一个静态的内部嵌套接口(相当于内部类):static interface Map.Entry<K,V>。Entry将键值对的对应关系封装成了对象,即键值对对象。这样我们在遍历Map集合时,就可以从每一个键值对对象(Entry)中获取对象的键与其对应的值。

接口Map.Entry<K,V>方法摘要:

修饰语和类型 方法 描述
K getKey() 返回此项对应的键
V getValue() 返回此项对应的值

Map集合通过entrySet()方法将集合中的映射关系对象存储到Set集合中:

修饰语和类型 方法 描述
Set< Map.Entry<K, V> > entrySet() 返回此映射中包含的映射关系的Set视图

public class MapDemo2 {
   
	public static void main(String[] args) {
   
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "abc");
		map.put(2, "bcd");
		map.put(3, "cde");
		//调用map集合方法entrySet()将集合中的映射关系对象,存储到Set集合
		Set<Map.Entry<Integer, String>> set = map.entrySet();
		//迭代Set集合
		Iterator<Map.Entry<Integer, String>> it = set.iterator();
		while (it.hasNext()) {
   
			//获取出的Set集合的元素,是映射关系对象
			// it.next 获取的是什么对象,也是Map.Entry对象
			Map.Entry<Integer, String> entry = it.next();
			// 通过映射关系对象的方法 getKet, getValue获取键值对
			Integer key = entry.getKey();
			String value = entry.getValue();
			System.out.println(key + ":" + value);
		}
		//增强for循环方式遍历集合
		for(Map.Entry<Integer, String> entry : map.entrySet()){
   
  			System.out.println(entry.getKey()+":"+entry.getValue());
  		}
	}
}

注意:
1.Map集合不能直接使用迭代器或者foreach(增强for)进行遍历。但是转成Set之后就可以使用了。
2.获取内部类对象语法:外部类.内部类

其他的方法如:remove、size、clear、equals、isEmpty等方法和Collection中的用法差不多,不作赘述。

4.Map集合实现类:

Map集合的实现类有HashMap和LinkedHashMap。

HashMap: 前面的大部分代码已经使用到了hashMap,这里继续再通过示例代码说明一些细节。要求:HashMap存储自定义对象Person,作为键、值出现。

Person类:

public class Person {
   
	private String name;
	private int age;
	
	@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;
	}
	@Override
	public boolean equals(Object obj) {
   
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) 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;
	}
	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;
	}
	public Person(String name, int age) {
   
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
   
		super();
	}
	@Override
	public String toString() {
   
		return "Person" + name + ":" + age ;
	}
}

注意:为保证键的唯一性,Person类需要重写hashCode和equals方法,可直接通过Eclipse快捷键Alt + Shift + S快速自动生成。这里有:Java中hashCode与equals用法

主函数类:

import java.util.HashMap;
import java.util.Map;

/* * 使用HashMap集合,存储自定义的对象 * 自定义对象,作为键出现,作为值出现 */
public class HashMapDemo {
   
	public static void main(String[] args) {
   
		function_1();
		function_2();
	}
	/* * HashMap 存储自定义对象Person,作为键出现 * 键的对象,是Person类型,值是字符串 * 为保证键的唯一性,Person类重写了hashCode和equals方法。如果不重写,将会出现输出相同键情况。 */
	public static void function_1(){
   
		HashMap<Person, String> map = new HashMap<Person, String>();
		map.put(new Person("小王",20), "自贡市");
		map.put(new Person("小舒",18), "成都市");
		map.put(new Person("小明",18), "长沙市");
		map.put(new Person("小李",19), "北京市");
		for(Person key : map.keySet()){
   
			String value = map.get(key);
			System.out.println(key+":"+value);
		}
		System.out.println("以增强for遍历输出:");
		for(Map.Entry<Person, String> entry : map.entrySet()){
   
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
	}
	
	/* * HashMap 存储自定义的对象Person,作为值出现 * 键的对象,是字符串,可以保证唯一性 */
	public static void function_2(){
   
		HashMap<String, Person> map = new HashMap<String, Person>();
		map.put("自贡市", new Person("小王",20));
		map.put("成都市", new Person("小舒",18));
		map.put("北京市", new Person("小李",19));
		for(String key : map.keySet()){
   
			Person value = map.get(key);
			System.out.println(key+":+value);
		}
		System.out.println("以增强for遍历输出:");
		for(Map.Entry<String, Person> entry : map.entrySet()){
   
			String key = entry.getKey();
			Person value = entry.getValue();
			System.out.println(key+":"+value);
		}
	}
}

LinkedHashMap: LinkedHashMap继承自HashMap类。它唯一的特点就是:保证了迭代的顺序

Hashtable: Hashtable依旧是基于哈希表的集合,它和HashMap的用法是一样的。那它有什么独特之处呢?

特点:
1.Hashtable是线程安全集合,运行速度较慢;而HashMap和之前所讲到的所有集合都是线程不安全集合,运行速度更快。
2.HashMap允许允许存储null键,null值;而Hashtable不允许存储null键,null值

由于Hashtable运行速度较慢的这个弊端,从JDK1.2开始,被更先进的HashMap取代了!但是,它被抛弃了,它有个孩子还活着,它有个子类Properties依然活跃在开发的舞台上。Properties 类可以和IO流共同配合,实现数据的持久性存储,它的用法又同父类Hashtable完全一样。

返回Java中集合类知识目录。

推荐了解:Java中方法的可变参数

本文来源MrKorbin,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/25326

发表评论