Map集合
-
Map接口中常用方法
-
执行路口
package cn.xiaoge.day15.demo01; /* java.util.Map<k, v>集合 Map集合的特点: 1. Map集合是一个双列集合, 一个元素包含两个值(一个key, 一个value) 2. Map集合中的元素, key和value的数据类型可以相同, 也可以不同 3. Map集合的元素, key是不允许重复的, value是可以重复的 4. Map集合的元素, key和value是意义对应 java.util.HashMap<k, v>集合 implements Map<k, v>接口 HashMap集合的特点: 1. HashMap集合底层是哈希表: 查询的速度特别的块 JDK1.8之前: 数组+单项链表 JDK1.8之后: 数组+单项链表/红黑树(链表的长度超过8): 提高查询的速度 2. HashMap集合是一个无序的集合, 存储元素和取出元素的顺序有可能不一致 java.util.LinkedHashMap<k, v>集合 extends HashMap<k, v>集合 LinkedHashMap的特点: 1. LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序) 2. LinkedHashMap集合是一个有序的集合, 存储元素和取出元素的顺序是一致的 */ import java.util.HashMap; import java.util.Map; public class Demo01Map { public static void main(String[] args) { show01(); System.out.println("=================="); show02(); System.out.println("=================="); show03(); System.out.println("=================="); show04(); } /* boolean containsKey(Object key) 判断集合中是否包含指定的键. 返回值: 包含, 返回true 不包含, 返回false */ private static void show04() { // 创建一个Map集合 Map<String, Integer> map = new HashMap<>(); map.put("赵丽颖", 168); map.put("杨颖", 165); map.put("林志玲", 178); System.out.println(map); // {林志玲=178, 赵丽颖=168, 杨颖=165} boolean b1 = map.containsKey("赵丽颖"); System.out.println("b1: " + b1); // b1: true boolean b2 = map.containsKey("赵颖"); System.out.println("b2: " + b2); // b2: false } /* public V get(Object key) 根据指定的键, 在map集合中获取对应的值. 返回值: V key存在, 返回对应的值 key不存在, 返回null */ private static void show03() { // 创建一个Map集合 Map<String, Integer> map = new HashMap<>(); map.put("赵丽颖", 168); map.put("杨颖", 165); map.put("林志玲", 178); System.out.println(map); // {林志玲=178, 赵丽颖=168, 杨颖=165} Integer v1 = map.get("杨颖"); System.out.println("v1: " + v1); // v1: 165 Integer v2 = map.get("迪丽热巴"); System.out.println("v2: " + v2); // v2: null } /* public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除, 返回被删除的元素的值. 返回值: V key存在, v返回被删除的值 key不存在, v返回null */ private static void show02() { // 创建一个Map集合 Map<String, Integer> map = new HashMap<>(); map.put("赵丽颖", 168); map.put("杨颖", 165); map.put("林志玲", 178); System.out.println(map); // {林志玲=178, 赵丽颖=168, 杨颖=165} Integer v1 = map.remove("林志玲"); System.out.println("v1: " + v1); // v1: 178 System.out.println(map); // {赵丽颖=168, 杨颖=165} // int v2 = map.remove("林志颖"); // 自动拆箱 BullPointerException Integer v2 = map.remove("林志颖"); System.out.println("v2: " + v2); // v2: null 没有返回null System.out.println(map); // {赵丽颖=168, 杨颖=165} } /* public V put(K key, V value); 把指定的键与指定的值添加到Map集合中. 返回值: 存储键值对的时候, key不重复, 返回值v是null 存储键值对的时候, key重复, 会使用新的value替换map中重复的value, 返回被替换的value值 */ private static void show01() { // 创建map集合对象, 多态 Map<String, String> map = new HashMap<>(); String v1 = map.put("权志龙", "金泫雅1"); System.out.println("v1: " + v1); // v1: null String v2 = map.put("权志龙", "金泫雅2"); System.out.println("v2: " + v2); // v2: 金泫雅1 System.out.println(map); // {权志龙=金泫雅2} map.put("冷锋", "龙小云"); map.put("伊志平", "小龙女"); map.put("杨过", "小龙女"); System.out.println(map); // {伊志平=小龙女, 杨过=小龙女, 权志龙=金泫雅2, 冷锋=龙小云} } } // 运行结果 v1: null v2: 金泫雅1 {权志龙=金泫雅2} {伊志平=小龙女, 杨过=小龙女, 权志龙=金泫雅2, 冷锋=龙小云} ================== {林志玲=178, 赵丽颖=168, 杨颖=165} v1: 178 {赵丽颖=168, 杨颖=165} v2: null {赵丽颖=168, 杨颖=165} ================== {林志玲=178, 赵丽颖=168, 杨颖=165} v1: 165 v2: null ================== {林志玲=178, 赵丽颖=168, 杨颖=165} b1: true b2: false
-
-
Map集合中常用方法
-
执行路口
package cn.xiaoge.day15.demo01; /* Map集合的第一种遍历方式: 通过键找值的方式 Map集合中的方法: Set<k> keySet() 返回此映射中包含的键的 Set 视图. 实现步骤: 1. 使用Map集合中的方法keySet(), 把Map集合所有的key取出来, 存储到一个Set集合中 2. 遍历set集合, 获取Map集合中的每一个key 3. 通过Map集合中的方法get(key), 通过key找到value */ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Demo02KeySet { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("赵丽颖", 168); map.put("杨颖", 165); map.put("林志玲", 178); // 1. 使用Map集合中的方法keySet(), 把Map集合所有的key取出来, 存储到一个Set集合中 Set<String> set = map.keySet(); // 2. 遍历set集合, 获取Map集合中的每一个key // 这里使用迭代器 Iterator<String> it = set.iterator(); while(it.hasNext()){ String key = it.next(); // 3. 通过Map集合中的方法get(key), 通过key找到value Integer value = map.get(key); System.out.println(key + "=" + value); } System.out.println("============================="); // 使用增强for遍历Set for(String key: set) { Integer value = map.get(key); System.out.println(key + "=" + value); } } } // 运行结果 林志玲=178 赵丽颖=168 杨颖=165 ============================= 林志玲=178 赵丽颖=168 杨颖=165
-
-
Map集合中常用方法
-
执行路口
package cn.xiaoge.day15.demo01; /* Map集合遍历的第二种方式: 使用Entry对象遍历 Map集合中的方法: Set<Map.Entry<K, V>> entrySet() 返回此映射中包含的映射关系的 Set 视图. 实现步骤: 1. 使用Map集合中的方法entrySet(), 把Map集合中多个Entry对象取出来, 存储到一个Set集合中 2. 遍历Set集合, 获取每一个Entry对象 3. 使用Entry对象中的方法getKey() 和 getValue()获取键与值 */ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Demo03EntrySet { public static void main(String[] args) { // 创建Map集合 Map<String, Integer> map = new HashMap<>(); map.put("赵丽颖", 168); map.put("杨颖", 165); map.put("林志玲", 178); // 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()获取键与值 System.out.println(entry.getKey() + "=" + entry.getValue()); } System.out.println("================"); // 使用增强for for (Map.Entry<String, Integer> entry: map.entrySet()) { System.out.println(entry.getKey() + "=" + entry.getValue()); } } } // 运行结果 林志玲=178 赵丽颖=168 杨颖=165 ================ 林志玲=178 赵丽颖=168 杨颖=165
-
-
HashMap存储自定义类型键值
-
Person类
package cn.xiaoge.day15.demo02; import java.util.Objects; public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, 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; } }
-
执行路口
package cn.xiaoge.day15.demo02; /* HashMap存储自定义类型键值 Map集合保证key是唯一的: 作为key的元素, 必须重写hashCode方法和equals方法, 以保证key唯一 */ import java.util.HashMap; import java.util.Map; import java.util.Set; public class Demo01HashMapSavePerson { public static void main(String[] args) { show01(); System.out.println("======================="); show02(); System.out.println("======================="); } /* HashMap存储自定义类型键值 key: Person类型 Person类就必须重写hashCode方法和equals方法, 以保证key唯一 value: String类型 可以重复 */ private static void show02() { // 创建HashMap集合 HashMap<Person, String> map = new HashMap<>(); // 王几何中添加数据 map.put(new Person("女王", 18), "英国"); map.put(new Person("秦始皇", 18), "秦国"); map.put(new Person("普京", 30), "俄罗斯"); map.put(new Person("女王", 18), "毛里求斯"); // 使用entrySet, 增强for遍历 Set<Map.Entry<Person, String>> set= map.entrySet(); for (Map.Entry<Person, String> entry: set) { System.out.println(entry.getKey() + "--->" + entry.getValue()); } } /* HashMap存储自定义类型键值 key: String类型 String类型重写HashCode方法和equals方法, 可以保证key唯一 value: Person类型 value可以重复(同名同年龄的人视为同一个) */ private static void show01() { // 创建HashMap集合 HashMap<String, Person> map = new HashMap<>(); map.put("北京", new Person("张三", 18)); map.put("上海", new Person("李四", 19)); map.put("广州", new Person("王五", 20)); map.put("北京", new Person("赵六", 18)); // 使用keySet和增强for Set<String> set = map.keySet(); for (String key: set){ System.out.println(key + "--->" + map.get(key)); } } } // 运行结果 上海--->Person{name='李四', age=19} 广州--->Person{name='王五', age=20} 北京--->Person{name='赵六', age=18} ======================= Person{name='女王', age=18}--->毛里求斯 Person{name='秦始皇', age=18}--->秦国 Person{name='普京', age=30}--->俄罗斯 =======================
-
-
LinkedHashMap集合
-
执行路口
package cn.xiaoge.day15.demo03; /* java.util.LinkedHashMap<K, V> extends HashMap<K, V> Map 接口的哈希表和链接列表实现, 具有可预知的迭代顺序. 底层原理: 哈希表 + 链表(记录元素的顺序) */ import java.util.HashMap; import java.util.LinkedHashMap; public class Demo01LinkedHashMap { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("a", "a"); map.put("c", "c"); map.put("b", "b"); map.put("a", "d"); System.out.println(map); // key不允许重复, 无序 {a=d, b=b, c=c} System.out.println("===================="); LinkedHashMap<String, String> linked = new LinkedHashMap<>(); linked.put("a", "a"); linked.put("c", "c"); linked.put("b", "b"); linked.put("a", "d"); System.out.println(linked); // key不允许重复, 有序 {a=d, c=c, b=b} } } // 运行结果 {a=d, b=b, c=c} ==================== {a=d, c=c, b=b}
-
-
Hashtable集合
-
执行路口
package cn.xiaoge.day15.demo03; /* java.util.Hashtable<k, v>集合 implements Map<k, v>接口 Hashtable: 底层也是一个哈希表, 是一个线程安全的集合, 是单线程集合, 速度慢 HashMap: 底层是一个哈希表, 是一个线程不安全的集合, 是多线程的集合, 速度块 HashMap集合(之前学的所有集合): 可以存储null值, null键 Hashtable集合, 不能存储null值, null键 Hashtable和Vector集合一样, 在JDK1.2版本之后被更先进的集合(HashMap, ArrayList)取代了 Hashtable的子类Properties依然活跃在历史舞台 Properties集合是一个唯一和IO流相结合的集合 */ import java.util.HashMap; import java.util.Hashtable; public class Demo02Hashtable { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put(null, "a"); map.put("b", "null"); map.put(null, null); System.out.println(map); // {null=null, b=null} Hashtable<String, String> table = new Hashtable<>(); // table.put(null, "a"); // NullPointerException // table.put("a", null); // NullPointerException // table.put(null, null); // NullPointerException } } // 运行结果 {null=null, b=null}
-
-
案例
-
执行路口
package cn.xiaoge.day15.demo03; /* 练习: 计算一个字符串每个字符出现次数 分析: 1. 使用Scanner获取用户输入的字符串 2. 创建Map集合, key是字符串中的字符, value是字符的个数 3. 遍历字符串, 获取每一个字符 4. 使用获取到的字符, 去Map集合判断key是否存在 key存在: 通过字符(key), 获取value(字符个数) value++; put(key, value)把心的value存到Map集合中 key不存在: put(key, 1) 5. 遍历Map集合, 输出结果 */ import java.util.HashMap; import java.util.Scanner; public class Demo03MapTest { public static void main(String[] args) { // 1. 使用Scanner获取用户输入的字符串 System.out.print("please input a string: "); Scanner sc = new Scanner(System.in); String str = sc.next(); // 2. 创建Map集合, key是字符串中的字符, value是字符的个数 HashMap<Character, Integer> map = new HashMap<>(); // 3. 遍历字符串, 获取每一个字符 char[] charArr = str.toCharArray(); for (char key: charArr) { // 4. 使用获取到的字符, 去Map集合判断key是否存在 if (map.containsKey(key)){ // key存在 Integer value = map.get(key); value++; map.put(key, value); } else { // key不存在 map.put(key, 1); } } // 5. 遍历Map集合, 输出结果 for (Character key:map.keySet()){ System.out.println(key + "=" + map.get(key)); } } } // 运行结果 please input a string: haufionawiufghaiw a=3 u=2 f=2 w=2 g=1 h=2 i=3 n=1 o=1
-