Java集合-Map接口(key-value)

Map接口的特点:①KV键值对方式存储②Key键唯一,Value允许重复③无序。

Map有四个实现类:1.HashMap类2.LinkedHashMap类3.TreeMap类4.Hashtable类

1.HashMap类:

存储结构:哈希表 = 数组Node[ ] + 链表(红黑树)

扩容方法:resize()

扩容机制:原数组的2倍

特点:①Key唯一,不允许重复②Value允许重复③无序

HashMap : KV键值对集合,key唯一,value允许重复
put()方法 :添加键值对,如果key不存在,则返回null; 如果key存在,则保存新value,返回旧

value
get()方法 :根据key,获取value,如果key存在,获取该元素的键值对的value值;如果不存在,

则获取该元素的键值对的value值为null;如果返回的value为null, 类型转换时,会发生空指针

java 复制代码
public static void main(String[] args) {
		
		// Map键值对集合
		//保存城市人口信息
		// key :城市名称.
		// val:人口数量
		HashMap<String,Integer> map = new HashMap<String,Integer>();
		map.put("X咸阳",1100);
		
		HashMap<String,Integer> anotherMap = new HashMap<String,Integer>();
		anotherMap.put("B北京", 2500);
		anotherMap.put("C长春", 300);
		anotherMap.put("D大连", 1000);
		map.putAll(anotherMap);
		anotherMap.put("D大连", 1000);  //key不允许重复
		map.put("E鄂尔多斯", 1000);//value不允许重复
		
		System.out.println(map);

	}

输出:

java 复制代码
{D大连=1000, E鄂尔多斯=1000, C长春=300, B北京=2500, X咸阳=1100}

put()与get()方法:

java 复制代码
public static void main(String[] args) {
	HashMap<String,Integer> cityMap = new HashMap<String,Integer>();
	
	//put()方法:添加键值对
	//如果key不存在,则返回null
	System.out.println(cityMap.put("X西安", 1100));
	System.out.println(cityMap.put("B北京", 2500));
	System.out.println(cityMap.put("C长春", 300));
	System.out.println(cityMap.put("D大连", 1000));
	//如果key存在,则保存新value,返回旧value
	System.out.println(cityMap.put("X西安", 1200));
	
	//get()方法:根据Key值,获取value
	//key存在
	int value1 = cityMap.get("B北京");
	System.out.println("B北京===>"+value1);
	
	//key不存在
	Integer value2 = cityMap.get("N南京");
	System.out.println("N南京"+value2);
	
	//如果返回的value为null,类型转换时,会发生空指针
	int value3 = cityMap.get("N南京");
	}

输出:

java 复制代码
null
null
null
null
1100
B北京===>2500
N南京null
Exception in thread "main" java.lang.NullPointerException
	at com.zad.day24_1_26_01.Text08.main(Text08.java:28)

遍历map:

遍历Map

方式1:获取所有的key,然后按照每个key获取对应的value

方式2:获取所有的value

方式3:将每个KV键值对按照Entry类型的对象,统一获取

方式1 :获取所有的key,然后按照每个key获取对应的value

java 复制代码
public static void main(String[] args) {
		HashMap<String,String[]> map = new HashMap<String,String[]>();
		
		map.put("华语", new String[] { "林俊杰", "陈奕迅", "邓紫棋", "薛之谦", "汪苏泷", "李荣浩" });
		map.put("欧美", new String[] { "贾斯丁比伯", "威肯", "艾兰沃克", "德雷克" });
		map.put("乐队", new String[] { "魔力红", "烟鬼组合", "共和时代", "辅音组合", "Linkin Park", "Westlife" });
		
		//遍历Map
		//方式1:获取所有的key,然后按照每个key获取对应的value
		Set<String> keys = map.keySet();//获取map中所有的key
		
		System.out.println("所有的key:"+keys);
		System.out.println("按照每个key,获取对应的value");
		
		Iterator<String> it = keys.iterator();
		while(it.hasNext()) {
			String key = it.next();//获取每个key
			String[] val = map.get(key);//按照key获取对应的value
			System.out.printf("%s ---> %s  \n",key,Arrays.toString(val));	
		}
		
		
		
	}

输出:

java 复制代码
所有的key:[华语, 乐队, 欧美]
按照每个key,获取对应的value
华语 ---> [林俊杰, 陈奕迅, 邓紫棋, 薛之谦, 汪苏泷, 李荣浩]  
乐队 ---> [魔力红, 烟鬼组合, 共和时代, 辅音组合, Linkin Park, Westlife]  
欧美 ---> [贾斯丁比伯, 威肯, 艾兰沃克, 德雷克]  

方式2:获取所有的value

java 复制代码
public static void main(String[] args) {
		HashMap<String,String[]> map = new HashMap<String,String[]>();
		
		map.put("华语", new String[] { "林俊杰", "陈奕迅", "邓紫棋", "薛之谦", "汪苏泷", "李荣浩" });
		map.put("欧美", new String[] { "贾斯丁比伯", "威肯", "艾兰沃克", "德雷克" });
		map.put("乐队", new String[] { "魔力红", "烟鬼组合", "共和时代", "辅音组合", "Linkin Park", "Westlife" });
		
		//遍历map
		//方式2:获取所有的value
		Collection<String[]> values=map.values();
		for(String[] array:values) {
			System.out.println(Arrays.toString(array));
		}
	
		
	}

输出:

java 复制代码
[林俊杰, 陈奕迅, 邓紫棋, 薛之谦, 汪苏泷, 李荣浩]
[魔力红, 烟鬼组合, 共和时代, 辅音组合, Linkin Park, Westlife]
[贾斯丁比伯, 威肯, 艾兰沃克, 德雷克]

方式3:将每个KV键值对按照Entry类型的对象,统一获取

java 复制代码
public static void main(String[] args) {
		HashMap<String, String[]> map = new HashMap<String, String[]>();

		map.put("华语", new String[] { "林俊杰", "陈奕迅", "邓紫棋", "薛之谦", "汪苏泷", "李荣浩" });
		map.put("欧美", new String[] { "贾斯丁比伯", "威肯", "艾兰沃克", "德雷克" });
		map.put("乐队", new String[] { "魔力红", "烟鬼组合", "共和时代", "辅音组合", "Linkin Park", "Westlife" });
		
		//遍历Map
		//方式3:将每个KV键值对按照Entry类型的对象,统一获取
		Set<Entry<String,String[]>> entrys = map.entrySet();
		for(Entry<String,String[]>  keyValue:entrys) {
			System.out.printf("%s--->%s\n",keyValue.getKey(),Arrays.toString(keyValue.getValue()));
		}
	}

输出:

java 复制代码
华语--->[林俊杰, 陈奕迅, 邓紫棋, 薛之谦, 汪苏泷, 李荣浩]
乐队--->[魔力红, 烟鬼组合, 共和时代, 辅音组合, Linkin Park, Westlife]
欧美--->[贾斯丁比伯, 威肯, 艾兰沃克, 德雷克]

常用方法:

  • 判断key是否存在: containsKey()方法
  • 根据key获取value,如果key不存在,则返回default默认值: getOrDefault()方法
  • 根据key,删除KV键值对:remove()方法
  • 获取键值对的数量:size()方法
java 复制代码
public static void main(String[] args) {
		//歌手分类
		HashMap<String, String[]> map=new HashMap<String, String[]>();
		
		map.put("华语", new String[] { "林俊杰", "陈奕迅", "邓紫棋", "薛之谦", "汪苏泷", "李荣浩" });
		map.put("欧美", new String[] { "贾斯丁比伯", "威肯", "艾兰沃克", "德雷克" });
		map.put("乐队", new String[] { "魔力红", "烟鬼组合", "共和时代", "辅音组合", "Linkin Park", "Westlife" });
		
		//判断key是否存在
		boolean isContains = map.containsKey("日韩");
		System.out.println(isContains);
		
		//根据key获取value,如果key不存在,则返回default默认值
		String[] value = map.getOrDefault("日韩", new String[] {});
		System.out.println(Arrays.toString(value));
		
		//根据key,删除KV键值对
		map.remove("欧美");
		System.out.println(map);
		
		//获取键值对的数量
		int size = map.size();
		System.out.println(size);
	}

输出:

java 复制代码
false
[]
{华语=[Ljava.lang.String;@3d8c7aca, 乐队=[Ljava.lang.String;@5ebec15}
2

应用例:统计英文字母、中文、数字、标点符号的个数

java 复制代码
public static void main(String[] args) {
		//统计英文字母、中文、数字、标点符号的个数
		String str = "OMG,你们的中英混搭真是各有千秋,但Someone丝毫掩盖不了你们那硬朗的英语底子!For eg.papi酱真的very有才华啊,哦买噶的,U6666666!!!罢特,someone也是成功地掩盖了自己小学程度的英语水平!这样式的,I是不会use的,because l hate 这种人very much~";

		//统计结果,保存到map中
		HashMap<String, Integer> map = new HashMap<String, Integer>();
//		map.put("letters", 0);
//		map.put("numbers", 0);
//		map.put("chinese", 0);
//		map.put("flags", 0);

		// 遍历字符串,判断每个字符
		for (int i = 0; i < str.length(); i++) {
			// 获取每一个字符
			char c = str.charAt(i);

			if (c >= 'A' && c < 'Z' || c > 'a' && c < 'z') {
				//获取一个字符
				int oldValue = map.getOrDefault("letters", 0);
				int newValue = oldValue + 1;
				map.put("letters", newValue);
			} else if (c > '0' && c < '9') {
				map.put("numbers", map.getOrDefault("numbers", 0)+1);
			} else if (c >= 0x4e00 && c <= 0x29fa5) {
				map.put("chinese", map.getOrDefault("chinese", 0) + 1);
			} else {
				map.put("flags", map.getOrDefault("flags", 0)+ 1);
			}
		}
		System.out.println(map);

	}

输出:

java 复制代码
{chinese=79, flags=16, numbers=7, letters=52}
2.LinkedHashMap类:

存储结构:数组+链表+红黑树,,维护使用链表,记录顺序

特点:①Key唯一,不允许重复②Value允许重复③有序④LinkedHashMap是HashMap的子类

应用例:统计每个字符出现的次数

java 复制代码
public static void main(String[] args) {
		//统计每个字符出现的次数
		//无序
		String str = "qurfkjcbsdjqpiurfufhdvlajydfgquyvhvaljhvqouygqhvhv";
//		HashMap<String,Integer> map1 = new HashMap<String, Integer>();
		//有序
		LinkedHashMap<String,Integer> map2 = new LinkedHashMap<String, Integer>();
		
		for(int i = 0;i<str.length();i++) {
			String key = str.substring(i,i+1);
			
			//判断key是否存在
			if(map2.containsKey(key)) {
				//该字符(key)存在
				map2.put(key, map2.get(key)+1);
			}else {
				//该字符不存在
				map2.put(key, 1);
			}
		}
		System.out.println(map2);
		
		
	}

输出:

java 复制代码
{q=5, u=5, r=2, f=4, k=1, j=4, c=1, b=1, s=1, d=3, p=1, i=1, h=5, v=6, l=2, a=2, y=3, g=2, o=1}
3.TreeMap类:

特点:①Key唯一,不允许重复②Value允许重复③按照Key自动排序④AbstractMap的子类

存储结构:树中的每个节点均是Entry内部类对象(红黑树)

例:按照key自动排序,通过key进行比较后排序!!!

java 复制代码
public static void main(String[] args) {
		//HashMap:无序,按照key计算保存位置
		//HashMap<String,String> map = new HashMap<String,String>();
		
		// TreeMap:按照key自动排序,通过key进行比较后排序
		TreeMap<String, String> map = new TreeMap<String, String>();

		map.put("SN201", "A1");
		map.put("SN111", "A2");
		map.put("SN107", "A3");
		map.put("SN191", "A4");
		map.put("SN100", "A5");
		map.put("SN103", "A6");
		map.put("SN2011", "A7");
		map.put("SN1031", "A8");
		map.put("SN1231", "A9");

		for (Entry<String, String> entry : map.entrySet()) {
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
	}

输出:

java 复制代码
SN100:A5
SN103:A6
SN1031:A8
SN107:A3
SN111:A2
SN1231:A9
SN191:A4
SN201:A1
SN2011:A7

调用TreeMap<>()的有参构造方法,重写compare()方法,按照大小排序

java 复制代码
public static void main(String[] args) {
		//HashMap:无序,按照key计算保存位置
		//HashMap<String,String> map = new HashMap<String,String>();
		
		// TreeMap:按照key自动排序,通过key进行比较后排序
		TreeMap<String, String> map = new TreeMap<String, String>(new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				int n1 = Integer.parseInt(o1.substring(2));
				int n2 = Integer.parseInt(o2.substring(2));

				return n1 - n2;
			}
		});

		map.put("SN201", "A1");
		map.put("SN111", "A2");
		map.put("SN107", "A3");
		map.put("SN191", "A4");
		map.put("SN100", "A5");
		map.put("SN103", "A6");
		map.put("SN2011", "A7");
		map.put("SN1031", "A8");
		map.put("SN1231", "A9");

		for (Entry<String, String> entry : map.entrySet()) {
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
	}

输出:

java 复制代码
SN100:A5
SN103:A6
SN107:A3
SN111:A2
SN191:A4
SN201:A1
SN1031:A8
SN1231:A9
SN2011:A7
4.Hashtable类

特点:①Key唯一,不允许重复②Value允许重复③key 和 value不允许为空,如果为null,则抛出NullPointerExceptino④线程安全,使用synchronized加锁,性能较差

存储结构:数组+链表

  • 允许使用null做key
  • 不允许使用null做value
java 复制代码
public static void main(String[] args) {
		
		HashMap<String, String> map=new HashMap<String, String>();
		map.put(null, "巴黎世家");//不允许使用null做key
		map.put("AAA", null);//允许使用null做value
		System.out.println(map);
		
		Hashtable<String, String> table=new Hashtable<String, String>();
		table.put(null, "巴黎世家");//不允许使用null做key
		table.put("AAA", null);//不允许使用null做value
		System.out.println(table);
		}

输出:

java 复制代码
{null=巴黎世家, AAA=null}
Exception in thread "main" java.lang.NullPointerException
	at java.util.Hashtable.put(Hashtable.java:465)
	at com.zad.day24_1_26_01.Text15.main(Text15.java:15)
相关推荐
天天扭码3 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶3 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺8 分钟前
Spring Boot框架Starter组件整理
java·spring boot·后端
zwjapple14 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five15 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序15 分钟前
vue3 封装request请求
java·前端·typescript·vue
前端每日三省17 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
凡人的AI工具箱30 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
陈王卜33 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、33 分钟前
Spring Boot 注解
java·spring boot