1.Map集合体系
Map集合体系概述(Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的):
在Map接口下,主要有两个实现类HashMap(LinkedHashMap是在HashMap基础上的另一个实现类)和TreeMap实现类。
- HashMap(由键决定特点):无序、不重复、无索引
- 用的最多(利用hashCode和equals计算存储位置)
- LinkedHashMap(由键决定特点):有序、不重复、无索引
- (利用hashCode和equals计算存储位置)在前者的基础上,加Linked,底层用双向链表维护集合元素存储的顺序
- HashMap(由键决定特点):按照大小默认升序排序、不重复、无索引
- TreeSet一般的必须要有排序规则,才能进行访问遍历
如果存储的只是基本类型:Integer或Double,默认排序便可以解决,这种可以直接访问
如果是引用类型的数据类型,程序便不能再直接去别出顺序,此时便必须重写排序规则,否则访问即报错
2.Map常用API
代码编译环境:JDK11
package My1_Map;
import java.util.*;
/**
* Map接口的集合,常用API
*/
public class Test0_Map_Methods {
public static void main(String[] args) {
/**
* 方法1:V put(K key, V value):添加键值对数据
* 1、当添加的键不存在时,添加成功,返回null
* 2、当添加的键存在是,会使用新值替换旧值,并返回旧值(相当于是修改方法)
*/
Map<String,String> map = new HashMap<>();
String put = map.put("法外狂徒", "张三");
System.out.println(put);
String put1 = map.put("法外狂徒", "李四");
System.out.println(put1);
map.put("雷电法王","杨永信");
map.put("沉鱼落雁","罗玉凤");
/**
* 方法2:int size():获取集合的键值对的对象个数
*/
System.out.println(map);//这里我们先看一下目前map集合中的元素
int size = map.size();
System.out.println("size =" + size);
/**
* 方法3:void clear():清空集合
*/
map.clear();
System.out.println("map =" + map);
/**
* 方法4:boolean isEmpty():判断集合是否为空
*/
boolean empty = map.isEmpty();
System.out.println(empty);
// 重新添加几条数据
map.put("东邪","黄药师");
map.put("西毒","欧阳锋");
map.put("南帝","一灯大师");
map.put("北丐","洪七公");
map.put("中神通","周伯通");
map.put("XX","YY");
/**
* 方法5:V get(Object key):根据键获取对应值
* 1、键存在,返回键对应的值
* 2、键不存在,返回null
*/
String key1 = "西毒";
String exist = map.get("key1");
System.out.println("exist(" + key1 + "的名字为):" + exist);
String notExist = map.get("加拿大电鳗");
System.out.println("notExist不存在的值结果:" + notExist);
/**
* 方法6:V remove(Object key):删除键对应的键值对,返回被删除的键值对中的值
* 1、键存在时:返回键对应的值
* 2、键不存在时:返回null
*/
String remove1 = map.remove("XX");
System.out.println("remove1 = " + remove1);
String remove2 = map.remove("加拿大电鳗");
System.out.println("remove1 = " + remove2);//不存在 “加拿大电鳗” 这个键,所以返回 null
/**
* 方法7:boolean containsKey(Object key):判断集合是否包含某个键(键是唯一的,相当于是精确查找)
* 1、键存在时:返回true
* 2、键不存在时:返回false
*/
boolean containsKey1 = map.containsKey("西毒");
System.out.println("containsKey1 = " + containsKey1);//true
boolean containsKey2 = map.containsKey("XXX");
System.out.println("containsKey2 = " + containsKey2);//false
/**
* 方法8:boolean containsValue(Object value):判断是否包含某个值
*/
boolean containsValue1 = map.containsValue("罗志祥");
System.out.println("containsValue1 = " + containsValue1);//包含,返回true
boolean containsValue2 = map.containsValue("罗玉凤");
System.out.println("containsValue2 = " + containsValue2);//不包含,返回false
/**
* 方法9:Set<K> keySet():获取Map集合 所有的键(Key),存储到Set集合中
*/
Set<String> keys = map.keySet();
System.out.println("keys = " + keys);
/**
* 方法10:Collection<V> values():获取Map集合 所有的值(value),存储到Collection集合中)
*/
Collection<String> values = map.values();
System.out.println("values = " + values);
/**
* 方法11:public void putAll(Map<? extends K, ? extends V> m)
* 将 B map中的所有键值对 添加到 A map中
* 1、如果A map中的键值对,在B map中已经存在,那么就修改B map中键对应的值
* 2、如果A map中的键值对,在B map中不存在,那么就添加到B map中
*/
HashMap<String, String> map1 = new HashMap<>();
map1.put("数学","Math");
map1.put("物理","Physics");
map1.put("化学","Chemistry");
HashMap<String, String> map2 = new HashMap<>();
map2.put("语文","Chinese");
map2.put("英语","English");
map2.put("数学","ShuXue");
map1.putAll(map2);
System.out.println("map1 = " + map1);
System.out.println("map2 = " + map2);
}
}
package My1_Map;
import java.util.*;
import java.util.function.BiConsumer;
/**
* Map集合,遍历方式
* 1.键找值
* 2.键值对
* 2.1 迭代器遍历
* 2.2 增强for遍历
* 2.3 Lambda遍历
* 3.获取所有值
*/
public class Test0_Map_Methods2 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("东邪","黄药师");
map.put("西毒","欧阳锋");
map.put("南帝","一灯大师");
map.put("北丐","洪七公");
map.put("中神通","周伯通");
/**
* 遍历方式1:键找值:先通过 Map 获取所有键的 集合,然后 对键的集合 遍历get到对应键的值,然后打印
* 步骤一:
* 方法:获取所有键的集合
* 构造:Set<K> keySet()
* 步骤二:
* 方法:根据键获取其对应的值
* 构造:V get(Object key)
*/
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
System.out.println("绰号:" + key + ",姓名:" + value);
}
/**
* 遍历方式2:键值对:获取到所有键值对的集合,然后遍历,调用 键值对entrySet的 api,获取 键和值,然后打印
* 步骤一:
* 方法:Set<Map.Entry<K,V>> entrySet():获取所有键值对的集合
* 当我们调用entrySet()方法,entrySet()底层就会将集合中的键和值,封装成一个Entry对象,
* Entry对象的对象类型,即Map的Entry类型,Entry对象的属性为(键,值),然后底层将这些封装的Entry对象放到一个Set集合中返回一个Map.Entry<泛型1, 泛型2>类型的集合给调用者
* 步骤二:
* 方法:获取键
* 构造:K getKey()
* 方法:获取值
* 构造:V getValue()
*/
Set<Map.Entry<String, String>> entries = map.entrySet();
// 2.1 迭代器遍历
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println("绰号:" + key + ",姓名:" + value);
}
// 2.2 增强for遍历
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println("绰号:" + key + ",姓名:" + value);
}
// 2.3 Lambda遍历
// default void forEach(BiConsumer<? super K,? super V> action)
// 底层原理:通过迭代器,获取键值对对象,再通过键值对对象,直接获取 键 和 值 ,然后传给accept(键,值)
map.forEach((key, value) -> System.out.println("绰号:" + key + ",姓名:" + value));
/**
* 遍历方式3:获取所有值
*/
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
}
}
3.HashMap demo
package My1_Map;
import My1_Map.pojo.Student;
import My1_Map.pojo.Teacher;
import java.util.HashMap;
import java.util.function.BiConsumer;
/**
* HashMap集合
* 特点:
* 1、无序、不重复、无索引
* 2、HashSet的底层是HashMap
* 3、HashMap底层数据结构是哈希表
* 4、HashMap存储自定义对象作为键,为了保证键的唯一性(去重),需要重写hashCode()以及equals()方法
*
* · HashMap集合是一种增删改查数据,性能都较好的集合
* · 但是它是无序、不能重复、没有索引支持的(由键决定特点,(值是可以重复的))
* · HashMap的键依赖hashCode方法和equals方法来保证键的唯一
* · 如果键存储的是自定义类型的对象,可以通过重写hashCode方法和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的,不再存储
*
* HashMap集合的底层原理:
* HashSet跟HashSetd的底层原理是一模一样的,都是基于哈希表实现的(根据哈希值%数组取余求出应该存储的位置)
* 实际上:原来学的Set系列集合的底层就是基于Map实现的,是指Set集合中的元素,只要键数据,不要值数据而已
*/
public class Test1_HashMap {
public static void main(String[] args) {
/**
* HashMap键的唯一 demo(不重写hashCode()以及equals()方法)
* 1.使用自定义对象 Teacher 作为键
* 2.字符串 作为值
* 3.Teacher没有重写 hashCode()以及equals()方法
* 结论:
* 创建同属性的 Teacher 对象,添加到 HashMap集合中,因为没有重写 hashCode()以及equals()方法,所以都可以添加到 集合中
*/
HashMap<Teacher, String> teacherStringHashMap = new HashMap<>();
teacherStringHashMap.put(new Teacher("张三",25),"南京");
teacherStringHashMap.put(new Teacher("张三",25),"北京");
teacherStringHashMap.put(new Teacher("张三",25),"上海");
teacherStringHashMap.put(new Teacher("张三",25),"深圳");
teacherStringHashMap.forEach((key,value) -> System.out.println("姓名:" + key + ",城市:" + value));
System.out.println("----------------------");
/**
* HashMap键的唯一 demo(重写hashCode()以及equals()方法)
* 1.使用自定义对象 Student 作为键
* 2.字符串 作为值
* 3.Student重写 hashCode()以及equals()方法
* 结论:
* 创建同属性的 Teacher 对象,添加到 HashMap集合中,因为重写 hashCode()以及equals()方法,所以只有一个被添加到 集合中,因为键的唯一性
*
* 为什么重写 hashCode()以及equals()方法,才能保证键的唯一性?
* 未重写,hashmap的键唯一性检验时,调用的是 Object 的 equals 和 hashcode方法(比较的是引用地址是否相同)
* 重写后,hashmap的键唯一性检验时,调用的是 Student 的 equals 和 hashcode方法(比较的是属性值是否相同)
*/
HashMap<Student, String> studentStringHashMap = new HashMap<>();
studentStringHashMap.put(new Student("张三",25),"南京");
studentStringHashMap.put(new Student("张三",25),"北京");
studentStringHashMap.put(new Student("张三",25),"上海");
studentStringHashMap.put(new Student("张三",25),"深圳");
studentStringHashMap.forEach((key,value) -> System.out.println("姓名:" + key + ",城市:" + value));
}
}
4.LinkedHashMap demo
package My1_Map;
import My1_Map.pojo.Student;
import java.util.LinkedHashMap;
import java.util.function.BiConsumer;
/**
* LinkedHashMap集合
* 特点:
* 有序、不重复、无索引
*
* 底层通过双向链表维护键的存储顺序
*
* 要使用对象作为键,必须重写equals()方法和hashCode()方法
*
* LinkedHashMap集合的底层原理:
* 底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外多了一个双链表的机制记录元素的顺序(这样来保证我们存入的先后顺序,在打印的时候也是按照该顺序打印出来)
* 实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap
*/
public class Test2_LinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<Student, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put(new Student("张三",20),"云南");
linkedHashMap.put(new Student("李四",21),"缅甸");
linkedHashMap.put(new Student("李四",21),"缅甸");
linkedHashMap.put(new Student("赵六",23),"老挝");
linkedHashMap.put(new Student("赵六",23),"老挝");
linkedHashMap.forEach((key,value) -> System.out.println("姓名:" + key + ",城市:" + value));
}
}
5.TreeMap demo
package My1_Map;
import My1_Map.pojo.Student;
import java.util.Comparator;
import java.util.TreeMap;
import java.util.function.BiConsumer;
/**
* TreeMap集合
* 特点:不重复,无索引,可排序(按照键的大小默认升序排序,只能对键排序, 不能对值排序, 维护键的有序性基于 对象是否实现Comparable接口或重写compareTo方法)
* 1、底层结构是红黑树
* 2、TreeSet底层就是TreeMap
* 3、添加自定义对象作为键需要指定排序规则
* 自然排序:自定义对象所属类需要实现Comparable接口,重写compareTo方法
* 比较器排序:在TreeMap集合构造方法中传递Comparator比较器对象,重写compareTo方法
* 注意:比较器规则优先级 > 自然排序规则
*
* 底层原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序
* TreeMap集合同样也支持两种方式来指定排序规则
* 1、让类实现Comparable接口,重写比较规则
* 2、TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,一遍用来指定比较规则
*/
public class Test3_TreeMap {
public static void main(String[] args) {
TreeMap<Student, String> treeMap = new TreeMap<>();
treeMap.put(new Student("张三",20),"云南");
treeMap.put(new Student("李四",21),"缅甸");
treeMap.put(new Student("李四",21),"缅甸");
treeMap.put(new Student("赵六",23),"老挝");
treeMap.put(new Student("赵六",23),"老挝");
treeMap.forEach((key, value) -> System.out.println("姓名:" + key + ",城市:" + value));
}
}
标签:体系,Map,HashMap,map,System,put,集合,println
From: https://blog.csdn.net/Mr_chen199409/article/details/139640984