示例"/>
java中Map、Entry键值对、LinkedHashMap、HashTable详解+示例
Java
Map、Entry键值对
java.util.Map<k,v>
Map集合的特点:
- Map是一个双列集合,一个元素包含两个值(一个key,一个value)。
- Map集合中的元素,key和value的数据类型可以相同,也可以不同。
- Map集合中的元素,key是不可以重复的,而value是可以重复的。
- Map集合中的元素,key和value是一一对应的,一个key对应一个value。
java.util.HashMap<k,v>集合 implements Map<k,v>
HashMap集合的特点:
- HashMap集合底层是哈希表,查询速度快
- HashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致
java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合
LinkedHashMap的特点;
- LinkedHashMap集合底层是哈希表+链表。
- LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的
常用方法:
- public V put(K key, V value)
定义:把指定的键与指定的值添加到Map集合中。
返回值 :v
存储键值对,key不重复,返回值v是null
存储键值对,key重复,会使用新的value替换map中重复的value,返回被替换的value。
package com.it.god.controller;import java.util.HashMap;
import java.util.Map;public class MapTest01 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();String v1 = map.put("张三", "李四");System.out.println("v1:" + v1);//v1:nullString v2 = map.put("张三", "王五");System.out.println("v2:" + v2);//v2:李四System.out.println(map);//要想往里添加,则参照下列方法map.put("血手人屠", "铁剑山河");map.put("心魔", "血菩萨");System.out.println(map);}}
....................................................................................................................
v1:null
v2:李四
{张三=王五}
{张三=王五, 血手人屠=铁剑山河, 心魔=血菩萨}
2.public V remove(Object key)
定义:把指定的键所对应的键值元素 在Map集合中删除,返回被删除元素的值。
返回值:v
key存在,v返回被删除的值
key不存在,v返回null
private static void test02(){Map<String, Integer> map = new HashMap<>();map.put("苏檀儿", 1);map.put("小婵", 2);map.put("聂云竹", 3);map.put("宁毅", 4);System.out.println(map);Integer v1 = map.remove("宁毅");System.out.println("v1:" + v1);//返回被删除key对应的值System.out.println(map);Integer v2 = map.remove("苏文昱");System.out.println("v2:" + v2);//返回nullSystem.out.println(map);}
...................................................................................................................
{聂云竹=3, 苏檀儿=1, 小婵=2, 宁毅=4}
v1:4
{聂云竹=3, 苏檀儿=1, 小婵=2}
v2:null
{聂云竹=3, 苏檀儿=1, 小婵=2}
- public V get(Object key)
定义:根据指定的键,在Map集合中获取对应的值。
返回值:
key存在,返回对应的value值
key不存在,返回null
private static void test03() {Map<String, Integer> map = new HashMap<>();map.put("苏檀儿", 1);map.put("小婵", 2);map.put("聂云竹", 3);map.put("宁毅", 4);System.out.println(map);Integer v1 = map.get("苏檀儿");System.out.println("v1:"+v1);//获取key键对应的value值Integer v2 = map.get("苏文方");System.out.println("v2:"+v2);//key不存在,获取不到值,返回null}.............................................................................................................{聂云竹=3, 苏檀儿=1, 小婵=2, 宁毅=4}v1:1v2:null
4.public boolean containsKey(Object key)
定义:判断集合中是否包含指定的键。
返回值:
包含返回true,不包含返回false。
private static void test04() {Map<String, Integer> map = new HashMap<>();map.put("苏檀儿", 1);map.put("小婵", 2);map.put("聂云竹", 3);map.put("宁毅", 4);System.out.println(map);boolean v1 = map.containsKey("苏檀儿");System.out.println("v1:"+v1);//在map中查找是否存在key键,存在返回trueboolean v2 = map.containsKey("苏文星");System.out.println("v2:"+v2);//在map中查找是否存在key键,不存在返回false}.............................................................................................................{聂云竹=3, 苏檀儿=1, 小婵=2, 宁毅=4}v1:truev2:false
方法 | 描述 |
---|---|
clear() | 删除 hashMap 中的所有键/值对 |
clone() | 复制一份 hashMap |
isEmpty() | 判断 hashMap 是否为空 |
size() | 计算 hashMap 中键/值对的数量 |
putAll() | 将所有键/值对添加到 hashMap 中 |
putIfAbsent() | 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。 |
containsValue() | 检查 hashMap 中是否存在指定的 value 对应的映射关系。 |
replace() | 替换 hashMap 中是指定的 key 对应的 value。 |
replaceAll() | 将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。 |
getOrDefault() | 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值 |
forEach() | 对 hashMap 中的每个映射执行指定的操作。 |
values() | 返回 hashMap 中存在的所有 value 值。 |
merge() | 添加键值对到 hashMap 中 |
compute() | 对 hashMap 中指定 key 的值进行重新计算 |
computeIfAbsent() | 对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中 |
computeIfPresent() | 对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。 |
示例:
public static void main(String[] args) {show01();}private static void show01() {HashMap<String,String > map = new HashMap<>();boolean result = map.isEmpty();//为空 trueSystem.out.println("集合是否为空" + result);map.put("苏檀儿", "宁曦");map.put("小婵", "宁忌");map.put("聂云竹", "宁雯雯");map.put("元锦儿", "宁珂");System.out.println(map);System.out.println("-----------");//putIfAbsent() 方法会先判断指定的键(key)是否存在,不存在则将键/值对插入到 HashMap 中//不存在该key,进行插入map.putIfAbsent("刘西瓜", "宁凝");System.out.println(map);System.out.println("-----------");result = map.isEmpty();//falseSystem.out.println("集合是否为空"+result);System.out.println("-----------");// containsValue() 方法,检测value中是否存在该值if(map.containsValue("宁曦")) {System.out.println("宁曦 存在于 map 中");}System.out.println("-----------");if (!map.containsValue("宁轶")) {map.put("呜呜呜", "宁轶");}System.out.println("Updated map HashMap: " + map);System.out.println("-----------");// 获得该 HashMap 中键/值对映射的数量int size = map.size();System.out.println("Size of HashMap: " + size);System.out.println("-----------");HashMap<String,String > v1 = (HashMap<String, String>) map.clone();System.out.println(v1);System.out.println("-----------");HashMap<String, String> map02 = new HashMap<>();map02.put("lalala", "aaa");// 将所有的映射关系从 map 添加到 map02map02.putAll(map);System.out.println("map02->>" + map02);System.out.println("-----------");map.clear();HashMap<String,String > maps = new HashMap<>();maps.put("1", "Google");maps.put("2", "BaiDu");maps.put("3", "SouGou");System.out.println("maps HashMap: " + maps);//replaceAll() 使用以下方式将value值转换为大写maps.replaceAll((key,value) -> value.toUpperCase());System.out.println("Updated maps HashMap: " + maps);//getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。String value1 = maps.getOrDefault("1", "not found");System.out.println(value1);System.out.println("-----------");String value2 = maps.getOrDefault("4", "not found");System.out.println(value2);System.out.println("-----------");show02();}private static void show02() {// 创建一个 HashMapHashMap<String, Integer> prices = new HashMap<>();//往 HashMap 中插入值prices.put("Shoes", 200);prices.put("Bag", 300);prices.put("Pant", 150);System.out.println(" Price: " + prices);// 返回所有value值组成的视图Collection<Integer> vips = prices.values();System.out.println(vips);//merge() 方法会先判断指定的 key 是否存在,如果不存在,则添加键值对到 hashMap 中。//匿名函数 lambda表达式 (oldValue, newValue) -> oldValue + newValue) 作为重新映射函数。Integer vvipInteger = prices.merge("shirt", 30, (oldValue,newValue) -> oldValue + newValue);//因为键 Shirt 并不在 prices 中,merge() 方法将映射 Shirt=100 插入到 prices,重新映射函数的执行结果被忽略。System.out.println("Price of Shirt: " + vvipInteger);System.out.println("-----------");//compute() 方法对 hashMap 中指定 key 的值进行重新计算。int newPrice = pricespute("Shoes", (key,value) -> value - value * 10/100);System.out.println("Discounted Price of Shoes: " + newPrice);System.out.println("Updated HashMap: " + prices);System.out.println("-----------");System.out.println("update Price: ");//通过 lambda 表达式使用 forEach()prices.forEach((key,value) -> {// value 价格减少百分之 10value = value - value * 10/100;System.out.println(key + "="+ value + " ");});System.out.println("-----------");show03();}private static void show03() {// 创建一个 HashMapHashMap<String, Integer> prices = new HashMap<>();// 往HashMap中添加映射项prices.put("Shoes", 200);prices.put("Bag", 300);prices.put("Pant", 150);System.out.println("HashMap: " + prices);//computeIfAbsent() 方法对 hashMap 中指定 key 的值进行重新计算,//如果不存在这个 key,则添加到 hasMap 中。int shirtPrice = pricesputeIfAbsent("Shirt", key -> 280);System.out.println("Price of Shirt: " + shirtPrice);// 输出更新后的HashMapSystem.out.println("Updated HashMap: " + prices);System.out.println("-----------");//当shirt映射关系存在时,将不改变其值。shirtPrice = pricesputeIfAbsent("Shirt", key -> 380);System.out.println("Price of Shirt: " + shirtPrice);// 输出更新后的HashMapSystem.out.println("Updated HashMap: " + prices);System.out.println("-----------");show04();}private static void show04() {// 创建一个 HashMapHashMap<String, Integer> prices = new HashMap<>();// 往HashMap中添加映射关系prices.put("Shoes", 200);prices.put("Bag", 300);prices.put("Pant", 150);System.out.println("HashMap: " + prices);//computeIfPresent() 方法对 hashMap 中指定 key 的值进行重新计算,//前提是该 key 存在于 hashMap 中。// 重新计算鞋加上10%的增值税后的价值int shoesPrice = pricesputeIfPresent("Shoes", (key,value) -> value + value * 10/100);System.out.println("Price of Shoes after : " + shoesPrice);// 输出更新后的HashMapSystem.out.println("Updated HashMap: " + prices);}
.................................................................................................................
集合是否为空true
{聂云竹=宁雯雯, 苏檀儿=宁曦, 小婵=宁忌, 元锦儿=宁珂}
-----------
{刘西瓜=宁凝, 聂云竹=宁雯雯, 苏檀儿=宁曦, 小婵=宁忌, 元锦儿=宁珂}
-----------
集合是否为空false
-----------
宁曦 存在于 map 中
-----------
Updated map HashMap: {刘西瓜=宁凝, 聂云竹=宁雯雯, 苏檀儿=宁曦, 呜呜呜=宁轶, 小婵=宁忌, 元锦儿=宁珂}
-----------
Size of HashMap: 6
-----------
{刘西瓜=宁凝, 聂云竹=宁雯雯, 苏檀儿=宁曦, 呜呜呜=宁轶, 小婵=宁忌, 元锦儿=宁珂}
-----------
map02->>{刘西瓜=宁凝, 聂云竹=宁雯雯, 苏檀儿=宁曦, lalala=aaa, 呜呜呜=宁轶, 小婵=宁忌, 元锦儿=宁珂}
-----------
maps HashMap: {1=Google, 2=BaiDu, 3=SouGou}
Updated maps HashMap: {1=GOOGLE, 2=BAIDU, 3=SOUGOU}
GOOGLE
-----------
not found
-----------Price: {Pant=150, Bag=300, Shoes=200}
[150, 300, 200]
Price of Shirt: 30
-----------
Discounted Price of Shoes: 180
Updated HashMap: {Pant=150, shirt=30, Bag=300, Shoes=180}
-----------
update Price:
Pant=135
shirt=27
Bag=270
Shoes=162
-----------
HashMap: {Pant=150, Bag=300, Shoes=200}
Price of Shirt: 280
Updated HashMap: {Pant=150, Shirt=280, Bag=300, Shoes=200}
-----------
Price of Shirt: 280
Updated HashMap: {Pant=150, Shirt=280, Bag=300, Shoes=200}
-----------
HashMap: {Pant=150, Bag=300, Shoes=200}
Price of Shoes after : 220
Updated HashMap: {Pant=150, Bag=300, Shoes=220}
Map集合遍历方式:
一、通过键找值的方式
Map集合中的方法:
public Set keySet()
定义:返回此映射中包含的键的set视图。
实现步骤:
- 使用map集合中的方法 keySet(),把map集合所有的key取出来,存储到一个Set集合中
- 遍历set集合,获取map集合中的每一个key
- 通过map集合中的方法get(key),通过key找到value
private static void test05() {Map<String, Integer> map = new HashMap<>();map.put("苏檀儿", 1);map.put("小婵", 2);map.put("聂云竹", 3);map.put("宁毅", 4);//使用map集合中的方法 keySet(),把map集合所有的key取出来,存储到一个Set集合中Set<String> set = map.keySet();//遍历set集合,获取map集合中的每一个key//1.使用迭代器遍历set集合Iterator<String> it = set.iterator();while(it.hasNext()){String key = it.next();//通过map集合中的方法get(key),通过key找到valueInteger value = map.get(key);System.out.println(key+"="+value);}System.out.println("------------------------------------------------------");//2.使用增强for遍历set集合for(String key : map.keySet()){Integer value = map.get(key);System.out.println(key+"="+value);}}
.....................................................................................................................
聂云竹=3
苏檀儿=1
小婵=2
宁毅=4
------------------------------------------------------
聂云竹=3
苏檀儿=1
小婵=2
宁毅=4
二、使用entry对象遍历
Map集合中的方法:public Set<Map.Entry<K,V>> entrySet()
定义:返回此映射中包含的映射关系的set视图。
实现步骤:
- 使用map集合中的方法entrySet(),把map集合集合中多个Entry对象取出来,存储到一个Set集合中。
- 遍历Set集合,获取每一个Entry对象
- 使用Entry对象中的getKey()和getValue()方法,获取键与值
private static void test06() {Map<String, Integer> map = new HashMap<>();map.put("苏檀儿", 1);map.put("小婵", 2);map.put("聂云竹", 3);map.put("宁毅", 4);// 1. 使用map集合中的方法entrySet(),把map集合集合中多个Entry对象取出来,存储到一个Set集合中。Set<Map.Entry<String, Integer>> set = map.entrySet();// 2. 遍历Set集合,获取每一个Entry对象// 使用迭代器遍历set集合Iterator<Map.Entry<String, Integer>> it = set.iterator();while (it.hasNext()) {Map.Entry<String, Integer> entry = it.next();// 3. 使用Entry对象中的getKey()和getValue()方法,获取键与值String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + "=" + value);}System.out.println("------------------------------------------------------");//使用增加for循环遍历set集合for (Map.Entry<String, Integer> entry : map.entrySet() ) {// 3. 使用Entry对象中的getKey()和getValue()方法,获取键与值String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + "=" + value);}}
.................................................................................................................
聂云竹=3
苏檀儿=1
小婵=2
宁毅=4
------------------------------------------------------
聂云竹=3
苏檀儿=1
小婵=2
宁毅=4
HashMap存储自定义类型键值
Map集合保证key是唯一的;
作为key的元素,必须重写hashCode和equals方法,以保证key唯一
①key:string类型
string类型重写hashCode和equals方法,可以保证key唯一
value:Persion类型
value可以重复(同名同年龄的视为同一个人)
public class Persion {private String name;private int age;public Persion() {}public Persion(String name, int age) {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;}@Overridepublic String toString() {return "Persion [name=" + name + ", age=" + age + "]";}
}
private static void show01() {// 创建HashMap集合HashMap<String, Persion> map = new HashMap<>();//往集合中添加元素map.put("宁毅", new Persion("立恒",21 ));map.put("苏檀儿", new Persion("檀儿",15 ));map.put("小婵", new Persion("婵儿",14 ));map.put("宁曦", new Persion("曦儿",6 ));map.put("宁忌", new Persion("龙傲天",2 ));//使用keySet加增强for循环遍历map集合Set<String> set = map.keySet();for(String key : set){Persion value = map.get(key);System.out.println(key+"-->"+value);}}
.................................................................................................................
宁忌-->Persion [name=龙傲天, age=2]
苏檀儿-->Persion [name=檀儿, age=15]
小婵-->Persion [name=婵儿, age=14]
宁曦-->Persion [name=曦儿, age=6]
宁毅-->Persion [name=立恒, age=21]
②key:Persion类型
Persion类型重写hashCode和equals方法,可以保证key唯一
value:string类型
value可以重复
public class Persion {private String name;private int age;public Persion() {}public Persion(String name, int age) {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;}@Overridepublic String toString() {return "Persion [name=" + name + ", age=" + age + "]";}
}
private static void show02() {// 创建HashMap集合HashMap<Persion,String > map = new HashMap<>();//往集合中添加元素map.put(new Persion("立恒",21 ),"宁毅" );map.put(new Persion("檀儿",15 ),"苏檀儿" );map.put(new Persion("婵儿",14 ),"小婵" );map.put(new Persion("曦儿",6 ),"宁曦" );map.put(new Persion("龙傲天",2 ),"宁忌" );map.put(new Persion("龙傲天",2 ),"无忌" );//使用entrySet加增强for循环遍历map集合Set<Map.Entry<Persion, String>> set = map.entrySet();for (Map.Entry<Persion, String> entry :set ) {Persion key = entry.getKey();String value = entry.getValue();System.out.println(key+"-->"+value); }}
.................................................................................................................
Persion [name=龙傲天, age=2]-->无忌
Persion [name=婵儿, age=14]-->小婵
Persion [name=龙傲天, age=2]-->宁忌
Persion [name=檀儿, age=15]-->苏檀儿
Persion [name=立恒, age=21]-->宁毅
Persion [name=曦儿, age=6]-->宁曦
key为Persion类型时,并不能保证是唯一的,这是因为Persion类中并没有重写hashcode和equals,将persion类修改如下:
public class Persion {private String name;private int age;public Persion() {}public Persion(String name, int age) {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;}@Overridepublic String toString() {return "Persion [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Persion other = (Persion) 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;}}
private static void show02() {// 创建HashMap集合HashMap<Persion,String > map = new HashMap<>();//往集合中添加元素map.put(new Persion("立恒",21 ),"宁毅" );map.put(new Persion("檀儿",15 ),"苏檀儿" );map.put(new Persion("婵儿",14 ),"小婵" );map.put(new Persion("曦儿",6 ),"宁曦" );map.put(new Persion("龙傲天",2 ),"宁忌" );map.put(new Persion("龙傲天",2 ),"无忌" );//使用entrySet加增强for循环遍历map集合Set<Map.Entry<Persion, String>> set = map.entrySet();for (Map.Entry<Persion, String> entry :set ) {Persion key = entry.getKey();String value = entry.getValue();System.out.println(key+"-->"+value); }}
.................................................................................................................
Persion [name=婵儿, age=14]-->小婵
Persion [name=曦儿, age=6]-->宁曦
Persion [name=立恒, age=21]-->宁毅
Persion [name=檀儿, age=15]-->苏檀儿
Persion [name=龙傲天, age=2]-->无忌
重新测试,保证key是唯一的
LinkedHashMap集合
java.util.LinkedHashMap<K,V> entends HashMap<K,V>
Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。
底层原理:
哈希表+链表(记录元素的顺序)是有序的
public static void main(String[] args) {HashMap<String,String > map = new HashMap<>();map.put("苏檀儿", "宁曦");map.put("小婵", "宁忌");map.put("聂云竹", "宁雯雯");map.put("元锦儿", "宁珂");System.out.println(map);// HashMap key不允许重复,且是无序的集合System.out.println("-----------------------------------------------");LinkedHashMap<String,String > linked = new LinkedHashMap<>();linked.put("苏檀儿", "宁曦");linked.put("小婵", "宁忌");linked.put("聂云竹", "宁雯雯");linked.put("元锦儿", "宁珂");System.out.println(linked);//LinkedHashMap key不允许重复,且是有序的集合}
.................................................................................................................
{聂云竹=宁雯雯, 苏檀儿=宁曦, 小婵=宁忌, 元锦儿=宁珂}
-----------------------------------------------
{苏檀儿=宁曦, 小婵=宁忌, 聂云竹=宁雯雯, 元锦儿=宁珂}
HashTable集合
java.util.Hashtable<K,V> implements Map<K,V>
HashTable:底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢
HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快
HashMap集合:可以存储null值,null键
HashTable集合:不能存储null值,null键
public static void main(String[] args) {HashMap<String,String > map = new HashMap<>();map.put(null, "苏檀儿");map.put("宁毅", null);map.put(null, null);System.out.println(map);//HashMap允许存在null值,null键Hashtable<String, String> table = new Hashtable<>();table.put(null, "杏儿");//发生报错,空指针异常,不允许存在null值,null键table.put("杏儿",null );//发生报错,空指针异常,不允许存在null值,null键table.put(null, null);//发生报错,空指针异常,不允许存在null值,null键}
.................................................................................................................
{null=null, 宁毅=null}
Exception in thread "main" java.lang.NullPointerExceptionat java.util.Hashtable.put(Hashtable.java:465)at com.it.god.hashtable.HashTableTest.main(HashTableTest.java:17)
更多推荐
java中Map、Entry键值对、LinkedHashMap、HashTable详解+示例
发布评论