记录:295
场景:Java的HashMap理解与应用。把对HashMap操作,从查、增、改、删的角度去理解和应用HashMap的API。
版本:
JDK 1.8
Spring Boot 2.6.3
名词:
API,应用程序接口(Application Programming Interface)。API是一些预定的函数,提供给应用程序访问。调用方无需关注API内部源码和内部工作机制等细节,只需根据API提供方发布的调用方式调用API就行。
一、基础
1.基础知识
(1)HashMap,全称java.util.HashMap。继承java.util.AbstractMap抽象类。实现java.util.Map、java.lang.Cloneable、java.io.Serializable接口。
(2)HashMap的key可以为null,且只能有一个为null的key。可以有多个key值对应的value为null。HashMap的key的需保证唯一性。
(3)HashMap是线程不安全的,在多线程并发的环境下,需要开发人员自己处理多线程的安全问题。
(4)HashMap的数据结构组成是:数组+链表+红黑树。注意本例是(JDK 1.8)。
(5)HashMap、Hashtable、ConcurrentHashMap。HashMap是线程不安全的,多线程并发需自行处理线程安全问题。Hashtable是线程安全,在设计线程安全方法上都添加了synchronized关键字。ConcurrentHashMap是线程安全,效率比Hashtable要高,因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。HashMap的执行效率比Hashtable高。
2.应用场景
在需要使用(key,value)键值对场景均可以使用。在微应用中本地缓存数据、从数据库读取数据以表字段和字段值方式存储时等。
3.函数列表
以下函数主要是java.util.Map接口定义的函数和java.lang.Cloneable接口的clone函数。
//java.util.Map接口函数
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
interface Entry<K,V>{}
boolean equals(Object o);
int hashCode();
default V getOrDefault(Object key, V defaultValue);
default void forEach(BiConsumer<? super K, ? super V> action);
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
default V putIfAbsent(K key, V value);
default boolean remove(Object key, Object value);
default boolean replace(K key, V oldValue, V newValue);
default V replace(K key, V value);
default V computeIfAbsent(K key,Function<? super K, ? extends V> mappingFunction);
default V computeIfPresent(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction);
default V compute(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction);
default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction);
//java.lang.Cloneable接口函数
public Object clone();
二、应用
1.创建
创建,就是创建ArrayList操作,就能得到一个实际Java对象。
1.1操作场景
操作场景,函数功能说明。
(1)使用new关键字创建HashMap对象实例
1.2操作实例
操作实例,函数应用实例。
/**
* 使用new关键字创建HashMap对象实例
*/
public static void f_new() {
// 1.使用new创建默认的HashMap
Map<String, GirlVo> map01 = new HashMap<>();
// 2.使用new创建的HashMap,设置容量
Map<String, GirlVo> map02 = new HashMap<>(100);
// 3.使用new创建的HashMap,设置容量,设置hash加载因子
Map<String, GirlVo> map03 = new HashMap<>(100, 0.85f);
// 4.使用new创建的HashMap,使用一个HashMap作为入参
Map<String, Object> map0401 = new HashMap<>();
map0401.put("2001", "杭州");
map0401.put("2002", "北京");
Map<String, Object> map04 = new HashMap<>(map0401);
}
2.查
查,就是查询操作。
2.1操作场景
操作场景,函数功能说明。
(1)使用forEach遍历HashMap。
(2)使用for循环和Map.Entry,遍历HashMap,Map.Entry是Map的内部接口。
(3)使用for循环和map.keySet()和map.values(),分别遍历HashMap的key和value,HashMap的所有key转换后存放在Set<K>;所有value转换后存放在Collection<V>。
(4)使用Iterator,遍历HashMap。
(5)使用entrySet和forEach,遍历HashMap。
(6)使用size,查看HashMap存放对象的个数。
(7)使用isEmpty,查看HashMap的size是否为0。
(8)使用containsKey,判断HashMap中是否包含指定的Key。
(9)使用containsValue,判断HashMap中是否包含指定的Value。
(10)使用get,获取HashMap的key对应的value对象。
(11)使用keySet,将HashMap中所有key转换为Set<K>,遍历Set<K>获取每个Key。
(12)使用values,将HashMap中的所有value转换为Collection<V>,遍历Collection<V>获取每个value。
(13)使用entrySet,将HashMap中转换为Set<Map.Entry<K,V>>,遍历结果集。
(14)使用hashCode,计算出HashMap的hashCode值。
(15)使用equals,计算两个HashMap是否相等。
(16)使用getOrDefault,从HashMap中获取key指定对象或者返回默认对象。
(17)使用clone,把HashMap拷贝一份。
2.2操作实例
操作实例,函数应用实例。
/**
* 1.1 使用forEach遍历HashMap
*/
public static void f1_1() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.遍历HashMap
map.forEach((key, value) -> {
System.out.println("gir信息,编号: " + key
+ ",名称: " + value.getGirlName());
});
}
/**
* 1.2 使用for循环和Map.Entry,遍历HashMap,Map.Entry是Map的内部接口
*/
public static void f1_2() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.遍历HashMap
for (Map.Entry<String, GirlVo> entry : map.entrySet()) {
System.out.println("girl编号: " + entry.getKey()
+ ",girl信息: " + entry.getValue());
}
}
/**
* 1.3 使用for循环和map.keySet()和map.values(),遍历HashMap
*/
public static void f1_3() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.遍历HashMap的key
for (String key : map.keySet()) {
System.out.println("key: " + key);
}
// 3.遍历HashMap的value
for (GirlVo value : map.values()) {
System.out.println("value: " + value);
}
}
/**
* 1.4 使用Iterator,遍历HashMap
*/
public static void f1_4() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.遍历HashMap
Iterator<Map.Entry<String, GirlVo>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, GirlVo> entry = iterator.next();
System.out.println("girl编号: " + entry.getKey()
+ ",girl信息: " + entry.getValue());
}
}
/**
* 1.5 使用entrySet和forEach,遍历HashMap
*/
public static void f1_5() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.遍历HashMap
map.entrySet().forEach(entry -> {
System.out.println("key: " + entry.getKey()
+ ",value: " + entry.getValue());
});
}
/**
* 1.6 使用size,查看HashMap存放对象的个数
*/
public static void f1_6() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.查看HashMap的size
int size = map.size();
// 3.打印结果
System.out.println("size = " + size);
}
/**
* 1.7 使用isEmpty,查看HashMap的size是否为0
*/
public static void f1_7() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.查看HashMap是否为空
boolean flag = map.isEmpty();
// 3.打印结果
System.out.println("result = " + flag);
}
/**
* 1.8 使用containsKey,判断HashMap中是否包含指定的Key
*/
public static void f1_8() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.查看是否包含指定的key
boolean flag = map.containsKey("1001");
// 3.打印结果
System.out.println("result = " + flag);
}
/**
* 1.9 使用containsValue,判断HashMap中是否包含指定的Value
*/
public static void f1_9() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.判断是否包含对象
boolean flag = map.containsValue("杭州");
// 3.打印结果
System.out.println("result = " + flag);
}
/**
* 1.10 使用get,获取HashMap的key对应的value对象
*/
public static void f1_10() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.获取对象
GirlVo girl = map.get("1001");
// 3.打印结果
System.out.println("result = " + girl);
}
/**
* 1.11 使用keySet,将HashMap中所有key转换为Set<K>,遍历Set<K>获取每个Key
*/
public static void f1_11() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.获取Set<String>
Set<String> set = map.keySet();
// 3.打印结果
for (String key : map.keySet()) {
System.out.println("key: " + key);
}
}
/**
* 1.12 使用values,将HashMap中的所有value转换为Collection<V>,遍历Collection<V>获取每个value
*/
public static void f1_12() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.获取Collection<GirlVo>
Collection<GirlVo> collection = map.values();
// 3.打印结果
for (GirlVo girlVo : collection) {
System.out.println("girlVo: " + girlVo.toString());
}
}
/**
* 1.13 使用entrySet,将HashMap中转换为Set<Map.Entry<K,V>>,遍历结果集.
* Entry<K,V>是Map的内部接口
*/
public static void f1_13() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.使用entrySet将HashMap中转换为Set<Map.Entry<K,V>>
Set<Map.Entry<String, GirlVo>> entrySet = map.entrySet();
// 3.打印结果
for (Map.Entry<String, GirlVo> entry : entrySet) {
System.out.println("key: " + entry.getKey() + ",value: " + entry.getValue());
}
}
/**
* 1.14 使用equals,计算两个HashMap是否相等
*/
public static void f1_14() {
// 1.获取HashMap
Map<String, Object> map01 = getMapCity();
Map<String, Object> map02 = getMapCity();
// 2.计算是否相等
boolean flag = map01.equals(map02);
// 3.打印结果
System.out.println("城市: " + flag);
}
/**
* 1.15 使用hashCode,计算出HashMap的hashCode值
*/
public static void f1_15() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.计算hashCode
int hash = map.hashCode();
// 3.打印结果
System.out.println("城市: " + hash);
}
/**
* 1.16 使用getOrDefault,从HashMap中获取key指定对象或者返回默认对象
*/
public static void f1_16() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.从HashMap中获取key指定对象或者返回默认对象
Object city = map.getOrDefault("1007", "厦门");
// 3.打印结果
System.out.println("城市: " + city);
}
/**
* 1.17 使用clone,把HashMap拷贝一份
*/
public static void f1_17() {
// 1.获取HashMap
HashMap<String, Object> map01 = getHashMapCity();
HashMap<String, Object> map02 = null;
// 2.使用clone克隆
map02 = (HashMap<String, Object>) map01.clone();
// 3.打印结果
map02.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
3.增
增,就是增加操作。
3.1操作场景
操作场景,函数功能说明。
(1)使用put,在HashMap增加一条数据,如果Key存在,则会覆盖Value。
(2)使用putAll,在HashMap添加一个Map。
(3)使用putIfAbsent,在HashMap添加一个对象,如果Key存在,则不会覆盖Value。
3.2操作实例
操作实例,函数应用实例。
/**
* 2.1 使用put,在HashMap增加一条数据,如果Key存在,则会覆盖Value
*/
public static void f2_1() {
// 1.创建HashMap
Map<String, Object> map = new HashMap<>();
// 2.新增一条数据
map.put("1001", "杭州");
map.put("1002", "北京");
}
/**
* 2.2 使用putAll,在HashMap添加一个Map
*/
public static void f2_2() {
// 1.创建HashMap对象map01
Map<String, Object> map01 = new HashMap<>();
map01.put("1001", "杭州");
map01.put("1002", "北京");
// 2.创建HashMap对象map02
Map<String, Object> map02 = new HashMap<>();
map02.put("1003", "厦门");
// 3.使用putAll把map01添加到map02
map02.putAll(map01);
// 4.遍历map02
map02.forEach((key, value) -> {
System.out.println(",编号: " + key
+ ",名称: " + value);
});
}
/**
* 2.3 使用putIfAbsent,在HashMap添加一个对象,如果Key存在,则不会覆盖Value
*/
public static void f2_3() {
// 1.创建HashMap对象map01
Map<String, Object> map01 = new HashMap<>();
map01.put("1001", "杭州");
map01.put("1002", "北京");
// 2.使用putIfAbsent添加一个对象,如果Key存在,则不会覆盖Value
Object obj01 = map01.putIfAbsent("1003", "厦门");
Object obj02 = map01.putIfAbsent("1001", "苏州");
// 3.遍历map01
map01.forEach((key, value) -> {
System.out.println("编号: " + key
+ ",名称: " + value);
});
}
4.改
改,就是修改操作。
4.1操作场景
操作场景,函数功能说明。
(1)使用replace,修改HashMap中指定key的value值
(2)使用replace,查找出HashMap中,指定的key的curValue,如果replace的入参oldValue和curValue相等,则执行put(key,newValue),把入参newValue替换掉原来对应的值。
(3)使用replaceAll,以函数式接口方式,修改指定key的value值。
(4)使用computeIfAbsent,取出HashMap的key对应value值,value为null,则把函数式接口里面值put到HashMap;value不为null,则不操作,直接返回key对应的value。
(5)使用computeIfAbsent,取出HashMap的key对应value值,value不为null,则把函数式接口的apply返回的新值put到HashMap;value为null,则不操作,直接返回null。
(6)使用compute,取出HashMap的key对应value值,函数式接口的apply返回的新值newValue,新值newValue为null,则根据key删除HashMap中(key,value),新值newValue为不null,则put(key,newValue)。
(7)使用merge,取出HashMap的key对应oldValue值,oldValue为null,则使用传入的value值,不为null则使用函数式接口的apply返回值,作为newValue,newValue为null,则使用remove(key)删除,newValue不为null,则使用put(key,newValue)。
4.2操作实例
操作实例,函数应用实例。
/**
* 3.1 使用replace,修改HashMap中指定key的value值
*/
public static void f3_1() {
// 1.获取HashMap
Map<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
// 2.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.修改一条数据
Object obj = map.replace("1001", "苏州");
// 4.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
/**
* 3.2 使用replace,查找出HashMap中,指定的key的curValue,
* 如果replace的入参oldValue和curValue相等,则执行put(key,newValue),把入参newValue替换掉原来对应的值
*/
public static void f3_2() {
// 1.获取HashMap
Map<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
// 2.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.修改一条数据
boolean flag = map.replace("1001", "杭州", "苏州");
// 4.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
/**
* 3.3 使用replaceAll,以函数式接口方式,修改指定key的value值
*/
public static void f3_3() {
// 1.获取HashMap
Map<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
// 2.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.修改一条数据
map.replaceAll((key, value) -> {
if (Objects.equals(key, "1001")) {
value = "厦门";
}
return value;
});
// 4.修改前遍历
System.out.println("修改前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
/**
* 3.4 使用computeIfAbsent,取出HashMap的key对应value值,
* value为null,则把函数式接口里面值put到HashMap;
* value不为null,则不操作,直接返回key对应的value
*/
public static void f3_4() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
map.put("1009", null);
// 2.执行computeIfAbsent操作
Object city = map.computeIfAbsent("1009", (key) -> {
return "宁波";
});
// 3.打印结果
System.out.println("城市: " + city);
}
/**
* 3.5 使用computeIfAbsent,取出HashMap的key对应value值,
* value不为null,则把函数式接口的apply返回的新值put到HashMap;
* value为null,则不操作,直接返回null
*/
public static void f3_5() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.执行computeIfPresent操作
Object city = map.computeIfPresent("1001", (key, value) -> {
if (Objects.equals(value, "杭州")) {
return "杭州A";
}
return value;
});
// 3.打印结果
System.out.println("城市: " + city);
}
/**
* 3.6 使用compute,取出HashMap的key对应value值,
* 函数式接口的apply返回的新值newValue,
* 新值newValue为null,则根据key删除HashMap中(key,value),
* 新值newValue为不null,则put(key,newValue)
*/
public static void f3_6() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.新值不为null
Object city01 = map.compute("1009", (key, value) -> {
return "厦门";
});
// 3.新值为null
Object city02 = map.compute("1001", (key, value) -> {
if (Objects.equals("杭州", value)) {
return null;
}
return value;
});
// 4.打印结果
System.out.println("城市: " + city01);
}
/**
* 3.7 使用merge,取出HashMap的key对应oldValue值,
* oldValue为null,则使用传入的value值,不为null则使用函数式接口的apply返回值,作为newValue,
* newValue为null,则使用remove(key)删除,
* newValue不为null,则使用put(key, newValue)
*/
public static void f3_7() {
// 1.获取HashMap
Map<String, Object> map = getMapCity();
// 2.新值不为null
Object city01 = map.merge("1009", "南京", (oldValue, value) -> {
return "南京";
});
// 3.打印结果
System.out.println("城市: " + city01);
}
5.删
删,就是删除操作。
5.1操作场景
操作场景,函数功能说明。
(1)使用remove,删除HashMap中一个对象,返回一个已经删除的对象。
(2)使用remove,删除HashMap中一个对象。
(3)使用clear,删除HashMap所有对象。
5.2操作实例
操作实例,函数应用实例。
/**
* 4.1 使用remove,删除HashMap中一个对象,返回一个已经删除的对象
*/
public static void f4_1() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.删除前遍历
System.out.println("删除前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.删除一条数据,返回删除的对象
Object obj = map.remove("1001");
// 4.删除后遍历
System.out.println("删除后遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
/**
* 4.2 使用remove,删除HashMap中一个对象
*/
public static void f4_2() {
// 1.获取HashMap
Map<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
// 2.删除前遍历
System.out.println("删除前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.删除一条数据,返回true,已经成功,返回false,没删除
boolean flag = map.remove("1001", "北京");
// 4.删除后遍历
System.out.println("删除后遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
/**
* 4.3 使用clear,删除HashMap所有对象
*/
public static void f4_3() {
// 1.获取HashMap
Map<String, GirlVo> map = getMap();
// 2.删除前遍历
System.out.println("删除前遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
// 3.删除所有对象
map.clear();
// 4.删除后遍历
System.out.println("删除后遍历:");
map.forEach((key, value) -> {
System.out.println("key: " + key + " ,value: " + value);
});
}
6.共用代码
6.1获取数据
(1)获取Map<String, GirlVo>。
(2)获取Map,包含编码和城市。
(3)获取HashMap,包含编码和城市。
/**
* 获取Map<String, GirlVo>
* */
public static Map<String, GirlVo> getMap() {
Map<String, GirlVo> map = new HashMap<>();
GirlVo girl01 = GirlVo.builder().girlId("1001").girlName("张一").age(27).height(169).cupSize("F").build();
GirlVo girl02 = GirlVo.builder().girlId("1002").girlName("王二").age(29).height(175).cupSize("B").build();
GirlVo girl03 = GirlVo.builder().girlId("1003").girlName("刘五").age(24).height(160).cupSize("B").build();
GirlVo girl04 = GirlVo.builder().girlId("1004").girlName("陈六").age(21).height(168).cupSize("C").build();
GirlVo girl05 = GirlVo.builder().girlId("1005").girlName("赵七").age(25).height(169).cupSize("C").build();
GirlVo girl06 = GirlVo.builder().girlId("1006").girlName("张八").age(26).height(165).cupSize("A").build();
map.put(girl01.getGirlId(), girl01);
map.put(girl02.getGirlId(), girl02);
map.put(girl03.getGirlId(), girl03);
map.put(girl04.getGirlId(), girl04);
map.put(girl05.getGirlId(), girl05);
map.put(girl06.getGirlId(), girl06);
return map;
}
/**
* 获取Map,包含编码和城市
*/
public static Map<String, Object> getMapCity() {
Map<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
map.put("1003", "苏州");
return map;
}
/**
* 获取HashMap,包含编码和城市
*/
public static HashMap<String, Object> getHashMapCity() {
HashMap<String, Object> map = new HashMap<>();
map.put("1001", "杭州");
map.put("1002", "北京");
map.put("1003", "苏州");
return map;
}
6.2JavaBean对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class GirlVo {
/**ID号*/
String girlId;
/**姓名*/
String girlName;
/**年龄*/
long age;
/**身高*/
double height;
/**罩杯*/
String cupSize;
}
以上,感谢。
2022年9月23日