【原】Java学习笔记029 - 映射
1 package cn.temptation; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class Sample01 { 7 public static void main(String[] args) { 8 /* 9 * Collection接口及其子接口、实现类 等 称为 单列集合 10 * Map接口及其子接口、实现类等 称为 双列集合 11 * 12 * 接口 Map<K,V>:映射,将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 13 * 14 * Map(映射)由两部分组成:键(Key)和值(Value) 15 * 16 * 特点: 17 * 1、一个映射不能包含重复的键 18 * 2、每个键最多只能映射到一个值 19 * 3、映射中的键值对是无序的 20 * 21 * 理解Map(映射): 22 * 联想地图,能唯一确定地点使用的是坐标,地图上没有两个相同的坐标 23 * 但是地图上可以有相同的地名,比如不同省份下的区县可能名字相同,但是它们的坐标是不同的 24 * 地图上的坐标就是键,地名就是值 25 * 26 * Map<K,V>接口的常用成员方法: 27 * 1、添加功能 28 * V put(K key, V value) :将指定的值与此映射中的指定键关联(可选操作)。 29 * 返回:以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。(如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。 30 * 31 * 2、删除功能 32 * void clear() :从此映射中移除所有映射关系(可选操作)。 33 * V remove(Object key) :如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 34 * 35 * 3、判断功能 36 * boolean containsKey(Object key) :如果此映射包含指定键的映射关系,则返回 true。 37 * boolean containsValue(Object value) :如果此映射将一个或多个键映射到指定值,则返回 true。 38 * 39 * boolean isEmpty() :如果此映射未包含键-值映射关系,则返回 true。 40 * 41 * 4、长度功能 42 * int size() :返回此映射中的键-值映射关系数。 43 * 44 */ 45 Map<String, String> map = new HashMap<>(); 46 47 System.out.println("map:" + map); // map:{} 48 49 // 1、添加功能 50 // 如果把Map的键值对理解为夫妻的话,那么其put方法可以认为是返回伴侣的前任 51 // System.out.println("map`s put:" + map.put("高祖", "杨开慧")); // map`s put:null 52 // System.out.println("map`s put:" + map.put("高祖", "贺子珍")); // map`s put:杨开慧 53 // System.out.println("map`s put:" + map.put("高祖", "江青")); // map`s put:贺子珍 54 55 map.put("秦皇", "嬴政"); 56 map.put("汉武", "刘彻"); 57 map.put("唐宗", "李世民"); 58 map.put("宋祖", "赵匡胤"); 59 map.put("一代天骄", "成吉思汗"); 60 // 键值对映射关系中,键相同的,通过put添加后显示的是最后的那个键值对或者说是最新的那个键值对 61 map.put("一代天骄", "蒋中正"); 62 63 System.out.println("map:" + map); // map:{汉武=刘彻, 宋祖=赵匡胤, 一代天骄=蒋中正, 唐宗=李世民, 秦皇=嬴政} 64 65 System.out.println("----------------------------------------------------"); 66 67 // 2、删除功能 68 // map.clear(); 69 // System.out.println("map:" + map); // map:{} 70 71 map.remove("唐宗"); 72 System.out.println("map:" + map); // map:{汉武=刘彻, 宋祖=赵匡胤, 一代天骄=蒋中正, 秦皇=嬴政} 73 74 System.out.println("map`s remove:" + map.remove("宋祖")); // map`s remove:赵匡胤 75 System.out.println("map:" + map); // map:{汉武=刘彻, 一代天骄=蒋中正, 秦皇=嬴政} 76 77 System.out.println("map`s remove:" + map.remove("西楚霸王")); // map`s remove:null 78 79 System.out.println("----------------------------------------------------"); 80 81 // 3、判断功能 82 System.out.println("map`s containsKey:" + map.containsKey("秦皇")); // map`s containsKey:true 83 System.out.println("map`s containsKey:" + map.containsKey("西楚霸王")); // map`s containsKey:false 84 85 System.out.println("map`s containsValue:" + map.containsValue("刘彻")); // map`s containsValue:true 86 System.out.println("map`s containsValue:" + map.containsValue("刘秀")); // map`s containsValue:false 87 88 map.clear(); 89 System.out.println("map`s isEmpty:" + map.isEmpty()); // map`s isEmpty:true 90 91 // 4、长度功能 92 System.out.println("map`s size:" + map.size()); // map`s size:0 93 } 94 }
1 package cn.temptation; 2 3 import java.util.Collection; 4 import java.util.HashMap; 5 import java.util.Map; 6 import java.util.Set; 7 8 public class Sample02 { 9 public static void main(String[] args) { 10 /* 11 * Map<K, V>接口的常用成员方法: 12 * 1、获取功能 13 * V get(Object key) :返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 14 * Set<K> keySet() :返回此映射中包含的键的 Set 视图。 15 * Collection<V> values() :返回此映射中包含的值的 Collection 视图。 16 */ 17 Map<String, String> map = new HashMap<>(); 18 19 map.put("休斯敦", "火箭"); 20 map.put("金州", "勇士"); 21 map.put("洛杉矶", "湖人"); 22 23 System.out.println(map.get("休斯敦")); // 火箭 24 System.out.println(map.get("金州")); // 勇士 25 System.out.println(map.get("洛杉矶")); // 湖人 26 27 System.out.println("-------------------------------"); 28 29 // key不能重复 30 // 键值对映射关系中,键相同的,通过put添加后显示的是最后的那个键值对或者说是最新的那个键值对 31 map.put("西雅图", "超音速"); 32 map.put("西雅图", "不眠夜"); 33 34 Set<String> set = map.keySet(); 35 36 for (String item : set) { 37 System.out.println(item); 38 } 39 40 System.out.println("-------------------------------"); 41 42 // value可以重复 43 map.put("夏洛特", "黄蜂"); 44 map.put("新奥尔良", "黄蜂"); 45 46 Collection<String> collection = map.values(); 47 48 for (String item : collection) { 49 System.out.println(item); 50 } 51 52 // 注意:取出的值的顺序 和 放入映射的顺序是不一致的,但是取出的值的顺序 和 取出的键的顺序一致 53 } 54 }
1 package cn.temptation; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 import java.util.Set; 7 8 public class Sample03 { 9 public static void main(String[] args) { 10 /* 11 * Map<K, V>接口的常用成员方法: 12 * Set<Map.Entry<K,V>> entrySet() :返回此映射中包含的映射关系的 Set 视图。 13 * 14 * 接口 Map.Entry<K,V>:映射项(键-值对)。 15 * 16 * Map.Entry<K,V>接口的常用成员方法: 17 * 1、K getKey() :返回与此项对应的键。 18 * 2、V getValue() :返回与此项对应的值。 19 */ 20 Map<String, String> map = new HashMap<>(); 21 22 map.put("德玛西亚之力", "盖伦"); 23 map.put("德邦总管", "赵信"); 24 map.put("无极剑圣", "易大师"); 25 26 // 遍历Map 27 28 // 方法1、通过Map接口的keySet方法、get方法 29 Set<String> keySet = map.keySet(); 30 for (String key : keySet) { 31 String value = map.get(key); 32 System.out.println("key:" + key + " <-----> " + "value:" + value); 33 } 34 35 System.out.println("-------------------------------------"); 36 37 // 方法2、通过Map接口的entrySet方法、Entry接口的getKey方法、getValue方法(常用写法) 38 Set<Entry<String,String>> set = map.entrySet(); 39 for (Entry<String, String> entry : set) { 40 String key = entry.getKey(); 41 String value = entry.getValue(); 42 System.out.println("key:" + key + " <-----> " + "value:" + value); 43 } 44 } 45 }
1 package cn.temptation; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 7 public class Sample04 { 8 public static void main(String[] args) { 9 /* 10 * 类 HashMap<K,V>:基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。 11 */ 12 Map<String, String> map = new HashMap<>(); 13 14 map.put("中国", "北京"); 15 map.put("美国", "华盛顿"); 16 map.put(null, null); 17 18 // 遍历 19 for (Entry<String, String> entry : map.entrySet()) { 20 String key = entry.getKey(); 21 String value = entry.getValue(); 22 System.out.println("key:" + key + " <-----> " + "value:" + value); 23 } 24 } 25 }
1 package cn.temptation; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 7 public class Sample05 { 8 public static void main(String[] args) { 9 // 需求:在map中存储学生信息(姓名和年龄)及学号,并进行遍历(以学号为key,以学生信息为value) 10 Map<String, Student> map = new HashMap<>(); 11 12 // Map中key这个字符串类型设为学号,通过学号确定唯一性,学生信息作为值 13 map.put("9526", new Student("张三", 20)); 14 map.put("9527", new Student("李四", 18)); 15 map.put("9528", new Student("王五", 22)); 16 // 因为key相同,所以覆盖了前面添加进去的Student对象 17 map.put("9526", new Student("赵六", 16)); 18 19 System.out.println("map:" + map); 20 21 // 遍历映射 22 for (Entry<String, Student> entry : map.entrySet()) { 23 String id = entry.getKey(); 24 Student temp = entry.getValue(); 25 System.out.println("学号为:" + id + "," + temp.toString()); 26 } 27 } 28 }
1 package cn.temptation; 2 3 import java.util.Collection; 4 import java.util.HashMap; 5 import java.util.Map; 6 import java.util.Set; 7 import java.util.Map.Entry; 8 9 public class Sample06 { 10 // 成员变量 11 private static Map<Student, String> map = new HashMap<>(); 12 13 public static void main(String[] args) { 14 // 需求:在map中存储学生信息(姓名和年龄)及学号,并进行遍历(以学生信息为key,以学号为value) 15 // 问题1:如果我们知道这两个学生对象其实指的是同一个人,该如何处理? 16 // 答:这样学号就不是判断学生的唯一性的标准,而是学生信息是判定学生唯一的依据 17 18 // 问题2:添加学生信息不同的对象,但是学号相同,也加入到map对象中,想避免学号的重复,该如何处理? 19 // 答:考虑制作自动学号的生成方法,并且制作学生信息判断去重的方法 20 21 // 因为map中的数据不同的成员方法都要使用,所以考虑提取出去作为成员变量 22 // Map<Student, String> map = new HashMap<>(); 23 24 // Map中key这个字符串类型设为学号,通过学号确定唯一性,学生信息作为值 25 // map.put(new Student("张三", 20), "9526"); 26 // map.put(new Student("李四", 18), "9527"); 27 // map.put(new Student("王五", 22), "9528"); 28 // map.put(new Student("张三", 20), "9520"); // 重写Studengt对象的hashCode方法和equals后,就不会出现两个张三 20岁的学生对象了 29 // map.put(new Student("赵六", 16), "9527"); 30 31 Student student1 = new Student("张三", 20); 32 if (checkStudent(student1)) { 33 map.put(student1, getCurrentID()); 34 } 35 36 Student student2 = new Student("李四", 18); 37 if (checkStudent(student2)) { 38 map.put(student2, getCurrentID()); 39 } 40 41 Student student3 = new Student("王五", 2); 42 if (checkStudent(student3)) { 43 map.put(student3, getCurrentID()); 44 } 45 46 Student student4 = new Student("赵六", 16); 47 if (checkStudent(student4)) { 48 map.put(student4, getCurrentID()); 49 } 50 51 Student student5 = new Student("张三", 20); 52 if (checkStudent(student5)) { 53 map.put(student5, getCurrentID()); 54 } 55 56 System.out.println("map:" + map); 57 58 // 遍历映射 59 for (Entry<Student, String> entry : map.entrySet()) { 60 Student temp = entry.getKey(); 61 String id = entry.getValue(); 62 System.out.println("学号为:" + id + "," + temp.toString()); 63 } 64 } 65 66 // 获取当前可以使用的学号 67 public static String getCurrentID() { 68 String result = "1"; 69 70 if (map.size() > 0) { 71 72 // 获取所有的学号,存入Collection对象 73 Collection<String> collection = map.values(); 74 75 int max = 0; 76 77 for (String item : collection) { 78 if (Integer.parseInt(item) > max) { 79 max = Integer.parseInt(item); 80 } 81 } 82 83 result = max + 1 + ""; 84 } 85 86 return result; 87 } 88 89 // 判断学生信息是否有重复 90 public static boolean checkStudent(Student student) { 91 boolean flag = true; 92 93 // 获取所有的学生信息,存入Set对象 94 Set<Student> keySet = map.keySet(); 95 96 for (Student item : keySet) { 97 if (item.equals(student)) { 98 flag = false; 99 break; 100 } 101 } 102 103 return flag; 104 } 105 }
1 package cn.temptation; 2 3 // 学生类 4 public class Student { 5 // 成员变量 6 private String name; 7 private int age; 8 9 // 构造函数 10 public Student() { 11 super(); 12 } 13 14 public Student(String name, int age) { 15 super(); 16 this.name = name; 17 this.age = age; 18 } 19 20 // 成员方法 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 public int getAge() { 30 return age; 31 } 32 33 public void setAge(int age) { 34 this.age = age; 35 } 36 37 // 为了唯一判断对象,重写hashCode方法和equals方法 38 @Override 39 public int hashCode() { 40 final int prime = 31; 41 int result = 1; 42 result = prime * result + age; 43 result = prime * result + ((name == null) ? 0 : name.hashCode()); 44 return result; 45 } 46 47 @Override 48 public boolean equals(Object obj) { 49 if (this == obj) 50 return true; 51 if (obj == null) 52 return false; 53 if (getClass() != obj.getClass()) 54 return false; 55 Student other = (Student) obj; 56 if (age != other.age) 57 return false; 58 if (name == null) { 59 if (other.name != null) 60 return false; 61 } else if (!name.equals(other.name)) 62 return false; 63 return true; 64 } 65 66 @Override 67 public String toString() { 68 return "学生 [姓名为:" + name + ", 年龄为:" + age + "]"; 69 } 70 }
1 package cn.temptation; 2 3 import java.util.LinkedHashMap; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 7 public class Sample07 { 8 public static void main(String[] args) { 9 /* 10 * 类 LinkedHashMap<K,V>:Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。 11 * 12 * 特点: 13 * 1、由HashMap保证唯一性 14 * 2、由链表保证有序性 15 */ 16 Map<String, String> map = new LinkedHashMap<>(); 17 18 map.put("无冕之王", "荷兰"); 19 map.put("桑巴军团", "巴西"); 20 map.put("亚洲三流", "中国"); 21 22 for (Entry<String, String> entry : map.entrySet()) { 23 System.out.println("美称:" + entry.getKey() + " <-----> 国家名称:" + entry.getValue()); 24 } 25 } 26 }
1 package cn.temptation; 2 3 import java.util.Map; 4 import java.util.Map.Entry; 5 import java.util.Set; 6 import java.util.TreeMap; 7 8 public class Sample08 { 9 public static void main(String[] args) { 10 /* 11 * 类 TreeMap<K,V>: 12 * 基于红黑树(Red-Black tree)的 NavigableMap 实现。 13 * 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 14 * 15 * 用法:类比TreeSet 16 */ 17 Map<String, String> map = new TreeMap<>(); 18 19 map.put("Q", "嬴政"); 20 map.put("H", "刘彻"); 21 map.put("T", "李世民"); 22 map.put("S", "赵匡胤"); 23 24 for (Entry<String, String> entry : map.entrySet()) { 25 String key = entry.getKey(); 26 String value = entry.getValue(); 27 System.out.println(key + " <-----> " + value); 28 } 29 30 System.out.println("------------------------------"); 31 32 Set<String> keySet = map.keySet(); 33 System.out.println("keyset:" + keySet); 34 35 for (String key : keySet) { 36 String value = map.get(key); 37 System.out.println(key + " <-----> " + value); 38 } 39 } 40 }
1 package cn.temptation; 2 3 import java.util.Comparator; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 import java.util.TreeMap; 7 8 public class Sample09 { 9 public static void main(String[] args) { 10 // 需求:使用TreeMap存储学生信息,姓名和年龄相同的学生只能存储一个,排序规则:先按年龄排序,年龄相同按姓名自然排序 11 12 // 思路:姓名和年龄相同的学生只能存储一个,也就是把学生信息作为键;和TreeSet一样,自定义排序规则:通过实现Comparable接口 或 Comparator接口 13 14 Map<Student, String> map = new TreeMap<>(new Comparator<Student>() { 15 @Override 16 public int compare(Student student1, Student student2) { 17 // 先比较年龄 18 int resultAge = student1.getAge() - student2.getAge(); 19 20 // 年龄相同比较姓名 21 int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge; 22 23 return result; 24 } 25 }); 26 27 map.put(new Student("张三", 20), "9526"); 28 map.put(new Student("李四", 18), "9527"); 29 map.put(new Student("王五", 20), "9528"); 30 map.put(new Student("张三", 20), "9529"); 31 32 for (Entry<Student, String> entry : map.entrySet()) { 33 Student temp = entry.getKey(); 34 String id = entry.getValue(); 35 System.out.println("学号为:" + id + "," + temp.toString()); 36 } 37 } 38 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.LinkedHashMap; 5 import java.util.Map; 6 import java.util.Map.Entry; 7 8 public class Sample10 { 9 public static void main(String[] args) { 10 // 需求:选择合适的容器结构,存储并显示数据 11 // 类别:篮球明星前三名:乔丹、邓肯、科比 12 // 类别:足球明星前五名:梅西、C罗、卡卡、伊布、哈维 13 14 // 思路:容器中可以再放入容器 15 16 // 写法1、使用数组存储(注意:不同数组的索引同步) 17 // 声明类别数组 18 String[] arrCategory = { "篮球", "足球" }; 19 // 声明球星数组 20 String[][] arrStar = { { "乔丹", "邓肯", "科比" }, { "梅西", "C罗", "卡卡", "伊布", "哈维" } }; 21 22 // 遍历数组 23 for (int i = 0; i < arrCategory.length; i++) { 24 StringBuffer sb = new StringBuffer(); 25 sb.append("类别:").append(arrCategory[i]).append("中前").append(arrStar[i].length).append("名:"); 26 27 for (int j = 0; j < arrStar[i].length; j++) { 28 sb.append(arrStar[i][j]).append("、"); 29 } 30 31 System.out.println(sb.substring(0, sb.length() - 1)); 32 } 33 34 System.out.println("--------------------------------------------------------"); 35 36 // 写法2、使用集合存储(整体使用Map映射,key存为类别,value存为存放了多个球星名字的ArrayList) 37 Map<String, ArrayList<String>> map = new LinkedHashMap<>(); 38 39 ArrayList<String> basketBallList = new ArrayList<>(); 40 basketBallList.add("乔丹"); 41 basketBallList.add("邓肯"); 42 basketBallList.add("科比"); 43 44 map.put("篮球", basketBallList); 45 46 ArrayList<String> soccerList = new ArrayList<>(); 47 soccerList.add("梅西"); 48 soccerList.add("C罗"); 49 soccerList.add("卡卡"); 50 soccerList.add("伊布"); 51 soccerList.add("哈维"); 52 53 map.put("足球", soccerList); 54 55 for (Entry<String, ArrayList<String>> entry : map.entrySet()) { 56 StringBuffer sb = new StringBuffer(); 57 58 String category = entry.getKey(); 59 ArrayList<String> list = entry.getValue(); 60 61 sb.append("类别:").append(category).append("中前").append(list.size()).append("名:"); 62 63 for (String item : list) { 64 sb.append(item).append("、"); 65 } 66 67 System.out.println(sb.substring(0, sb.length() - 1)); 68 } 69 } 70 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.LinkedHashMap; 6 import java.util.Map; 7 import java.util.Map.Entry; 8 9 public class Sample11 { 10 public static void main(String[] args) { 11 // 需求: 12 // 存储并显示2016年NBA东西部决赛 13 // 东部:克利夫兰<----->骑士、明尼苏达<----->森林狼 14 // 西部:休斯敦<----->火箭、金州<----->勇士 15 // 存储并显示2015年NBA东西部决赛 16 // 东部:克利夫兰<----->骑士、亚特兰大<----->老鹰 17 // 西部:洛杉矶<----->湖人、金州<----->勇士 18 19 // 思路:复杂问题分解为若干个简单问题 20 21 Map<String, String> map1 = new LinkedHashMap<>(); 22 map1.put("克利夫兰", "骑士"); 23 map1.put("明尼苏达", "森林狼"); 24 25 Map<String, String> map2 = new LinkedHashMap<>(); 26 map2.put("休斯敦", "火箭"); 27 map2.put("金州", "勇士"); 28 29 Map<String, Map<String, String>> mapArea2016 = new LinkedHashMap<>(); 30 mapArea2016.put("东部", map1); 31 mapArea2016.put("西部", map2); 32 33 // 把2016年的数据封装在对象中 34 Record record2016 = new Record(); 35 record2016.setYear(2016); 36 record2016.setMapArea(mapArea2016); 37 38 Map<String, String> map3 = new LinkedHashMap<>(); 39 map3.put("克利夫兰", "骑士"); 40 map3.put("亚特兰大", "老鹰"); 41 42 Map<String, String> map4 = new LinkedHashMap<>(); 43 map4.put("洛杉矶", "湖人"); 44 map4.put("金州", "勇士"); 45 46 Map<String, Map<String, String>> mapArea2015 = new LinkedHashMap<>(); 47 mapArea2015.put("东部", map3); 48 mapArea2015.put("西部", map4); 49 50 // 把2015年的数据封装在对象中 51 Record record2015 = new Record(); 52 record2015.setYear(2015); 53 record2015.setMapArea(mapArea2015); 54 55 // 创建存储数据记录的集合 56 Collection<Record> collectionNBA = new ArrayList<>(); 57 collectionNBA.add(record2016); 58 collectionNBA.add(record2015); 59 60 StringBuffer sb = new StringBuffer(); 61 62 // 遍历 63 for (Record record : collectionNBA) { 64 sb.append(record.getYear()).append("年NBA东西部决赛:").append("\r\n"); 65 66 for (Entry<String, Map<String, String>> entryArea : record.getMapArea().entrySet()) { 67 sb.append(entryArea.getKey()).append(":"); 68 69 Map<String, String> mapCity = entryArea.getValue(); 70 71 StringBuffer sbTemp = new StringBuffer(); 72 73 for (Entry<String, String> entry : mapCity.entrySet()) { 74 sbTemp.append(entry.getKey()).append("<------>").append(entry.getValue()).append(","); 75 } 76 77 sb.append(sbTemp.substring(0, sbTemp.length() - 1)); 78 sb.append("\r\n"); 79 } 80 81 sb.append("\r\n"); 82 } 83 84 System.out.println(sb); 85 } 86 }
1 package cn.temptation; 2 3 import java.util.LinkedHashMap; 4 import java.util.Map; 5 6 /** 7 * 数据记录类 8 */ 9 public class Record { 10 // 成员变量 11 // 数据记录年份 12 private int year; 13 // 数据记录内容 14 private Map<String, Map<String, String>> mapArea = new LinkedHashMap<>(); 15 16 // 构造函数 17 public Record() { 18 super(); 19 } 20 21 public Record(int year, Map<String, Map<String, String>> mapArea) { 22 super(); 23 this.year = year; 24 this.mapArea = mapArea; 25 } 26 27 // 成员方法 28 public int getYear() { 29 return year; 30 } 31 32 public void setYear(int year) { 33 this.year = year; 34 } 35 36 public Map<String, Map<String, String>> getMapArea() { 37 return mapArea; 38 } 39 40 public void setMapArea(Map<String, Map<String, String>> mapArea) { 41 this.mapArea = mapArea; 42 } 43 44 @Override 45 public String toString() { 46 return "数据 [年份为:" + year + ", 内容为:" + mapArea + "]"; 47 } 48 }
1 package cn.temptation; 2 3 import java.util.LinkedHashMap; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 7 public class Sample12 { 8 public static void main(String[] args) { 9 // 需求:使用集合相关知识统计"javaisgoodisbetterisbestisamazing"中各个字符出现的次数 10 // 显示:字符j:1次、字符a:4次、... 11 12 // 思路: 13 // 1、既然统计的是字符出现的次数,所以把字符串转换为字符数组 14 // 2、创建一个map集合用来存储字符及其出现次数的关系映射,设置key为字符,value为出现次数 15 // 3、遍历字符数组,将得到的字符(key)传递map映射的get方法找到对应出现的次数(value) 16 // A:如果返回值为null,说明map映射中没有该字符及其出现次数的映射关系,那么map中存储下来这个映射关系 17 // B:如果返回值不为null,说明map映射中存在该字符及其出现次数的映射关系,那么将value值+1,再存储下来 18 19 String str = "javaisgoodisbetterisbestisamazing"; 20 char[] arr = str.toCharArray(); 21 Map<Character, Integer> map = new LinkedHashMap<>(); 22 23 // 遍历字符数组 24 for (char item : arr) { 25 // 根据各个字符传入map集合中查找 26 Integer count = map.get(item); 27 28 if (count == null) { 29 // 如果返回值为null,说明map映射中没有该字符及其出现次数的映射关系,那么map中存储下来这个映射关系 30 map.put(item, 1); 31 } else { 32 // 如果返回值不为null,说明map映射中存在该字符及其出现次数的映射关系,那么将value值+1,再存储下来 33 count++; 34 // 注意:具有相同key的键值对,最新的键值对会覆盖之前的键值对 35 map.put(item, count); 36 } 37 } 38 39 // 遍历map集合 40 for (Entry<Character, Integer> entry : map.entrySet()) { 41 Character key = entry.getKey(); 42 Integer value = entry.getValue(); 43 System.out.println("字符" + key + ":" + value + "次"); 44 } 45 } 46 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.List; 7 8 public class Sample13 { 9 public static void main(String[] args) { 10 /* 11 * 类 Collections: 12 * 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。 13 * 它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。 14 * 15 * Collections类的常用成员方法: 16 * 1、static <T extends Comparable<? super T>> void sort(List<T> list) :根据元素的自然顺序 对指定列表按升序进行排序。 17 * 18 * 2、static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) :使用二分搜索法搜索指定列表,以获得指定对象。 19 * 返回:如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。 20 * 插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。 21 * 注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。 22 * 23 * 3、static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) :根据元素的自然顺序,返回给定 collection 的最大元素。 24 * 25 * 4、static void reverse(List<?> list) :反转指定列表中元素的顺序。 26 * 27 * 5、static void shuffle(List<?> list) :使用默认随机源对指定列表进行置换。 28 * 29 */ 30 31 Collection<Integer> collection = new ArrayList<>(); 32 33 collection.add(2); 34 collection.add(3); 35 collection.add(5); 36 collection.add(4); 37 collection.add(1); 38 39 System.out.println("初始集合:" + collection); // 初始集合:[2, 3, 5, 4, 1] 40 41 Collections.sort((List<Integer>)collection); 42 System.out.println("使用排序:" + collection); // 使用排序:[1, 2, 3, 4, 5] 43 44 System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 2)); // 1 45 System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 0)); // -1 46 System.out.println("二分查找:" + Collections.binarySearch((List<Integer>)collection, 5)); // 4 47 48 System.out.println("最大值:" + Collections.max(collection)); // 5 49 50 Collections.reverse((List<Integer>)collection); 51 System.out.println("使用反转:" + collection); // 使用反转:[5, 4, 3, 2, 1] 52 53 Collections.shuffle((List<Integer>)collection); 54 System.out.println("随机置换:" + collection); 55 } 56 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.Comparator; 7 import java.util.List; 8 9 public class Sample14 { 10 public static void main(String[] args) { 11 /* 12 * Collections类的常用成员方法: 13 * 1、static <T> void sort(List<T> list, Comparator<? super T> c) :根据指定比较器产生的顺序对指定列表进行排序。 14 */ 15 Collection<Student> collection = new ArrayList<>(); 16 17 collection.add(new Student("张三", 20)); 18 collection.add(new Student("李四", 18)); 19 collection.add(new Student("王五", 22)); 20 collection.add(new Student("张飞", 20)); 21 22 // 语法错误:The method sort(List<T>) in the type Collections is not applicable for the arguments (List<Student>) 23 // Collections.sort((List<Student>)collection); 24 25 Collections.sort((List<Student>)collection, new Comparator<Student>() { 26 @Override 27 public int compare(Student student1, Student student2) { 28 // 先比较年龄 29 int resultAge = student1.getAge() - student2.getAge(); 30 31 // 年龄相同再比较姓名 32 int result = (resultAge == 0) ? student1.getName().compareTo(student2.getName()) : resultAge; 33 34 return result; 35 } 36 }); 37 38 // 遍历 39 for (Student item : collection) { 40 System.out.println(item); 41 } 42 } 43 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.List; 7 8 public class Sample15 { 9 public static void main(String[] args) { 10 // 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(无序) 11 // 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker 12 // 花色:♥ ◆ ♠ ♣ 13 14 // 思路: 15 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王) 16 // 2、把牌放入一个容器中 17 // 3、洗牌(考虑使用集合工具类Collections的shuffle方法) 18 // 4、发牌 19 // 5、看牌 20 21 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王) 22 // 创建花色集合 23 Collection<String> colors = new ArrayList<>(); 24 colors.add("♥"); 25 colors.add("◆"); 26 colors.add("♠"); 27 colors.add("♣"); 28 29 // 创建数字集合 30 Collection<String> numbers = new ArrayList<>(); 31 numbers.add("A"); 32 for (int i = 2; i <= 10; i++) { 33 numbers.add(String.valueOf(i)); 34 } 35 numbers.add("J"); 36 numbers.add("Q"); 37 numbers.add("K"); 38 39 // 2、把牌放入一个容器中 40 Collection<String> poker = new ArrayList<>(); 41 42 for (String color : colors) { 43 for (String number : numbers) { 44 poker.add(color.concat(number)); 45 } 46 } 47 48 poker.add("BlackJoker"); 49 poker.add("RedJoker"); 50 51 // System.out.println("一副牌:" + poker); 52 53 // 3、洗牌(考虑使用集合工具类Collections的shuffle方法) 54 Collections.shuffle((List<String>)poker); 55 56 // System.out.println("洗一副牌:" + poker); 57 58 // 4、发牌 59 // 声明剩余底牌数量 60 int remain = 3; 61 // 声明三个玩家对象和一个底牌对象 62 Collection<String> player1 = new ArrayList<>(); 63 Collection<String> player2 = new ArrayList<>(); 64 Collection<String> player3 = new ArrayList<>(); 65 Collection<String> last = new ArrayList<>(); 66 67 for (int i = 0; i < poker.size(); i++) { 68 if (i >= poker.size() - remain) { // 留下底牌 69 last.add(((List<String>)poker).get(i)); 70 } else if (i % 3 == 0) { // 给第一个玩家发牌 71 player1.add(((List<String>)poker).get(i)); 72 } else if (i % 3 == 1) { // 给第二个玩家发牌 73 player2.add(((List<String>)poker).get(i)); 74 } else if (i % 3 == 2) { // 给第三个玩家发牌 75 player3.add(((List<String>)poker).get(i)); 76 } 77 } 78 79 // 5、看牌 80 lookPoker("玩家1", player1); 81 lookPoker("玩家2", player2); 82 lookPoker("玩家3", player3); 83 lookPoker("底牌", last); 84 } 85 86 /** 87 * 看牌方法 88 * @param name 玩家名 89 * @param collection 手牌集合 90 */ 91 public static void lookPoker(String name, Collection<String> collection) { 92 System.out.println(name + "的手牌是:"); 93 for (String item : collection) { 94 System.out.print(item + " "); 95 } 96 // 换行 97 System.out.println(); 98 } 99 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.Comparator; 7 import java.util.List; 8 import java.util.Set; 9 import java.util.TreeSet; 10 11 public class Sample16 { 12 public static void main(String[] args) { 13 // 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(有序) 14 // 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker 15 // 花色:♥ ◆ ♠ ♣ 16 // 顺序规则:牌的规则:3 < 4 < 5 < ... < 10 < J < Q < K < A < 2 < BlackJoker < RedJoker 17 // 花色的规则(牌相同时)♥ ♠ ♣ ◆ 18 19 // 思路1: 20 // 在发牌时,通过比较器的使用,直接按规则排列玩家手中牌和底牌 21 22 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王) 23 // 创建花色集合 24 Collection<String> colors = new ArrayList<>(); 25 colors.add("♥"); 26 colors.add("◆"); 27 colors.add("♠"); 28 colors.add("♣"); 29 30 // 创建数字集合 31 Collection<String> numbers = new ArrayList<>(); 32 numbers.add("A"); 33 for (int i = 2; i <= 10; i++) { 34 numbers.add(String.valueOf(i)); 35 } 36 numbers.add("J"); 37 numbers.add("Q"); 38 numbers.add("K"); 39 40 // 2、把牌放入一个容器中 41 Collection<Card> poker = new ArrayList<>(); 42 43 for (String color : colors) { 44 for (String number : numbers) { 45 Card temp = new Card(); 46 temp.setColor(color); 47 temp.setNumber(number); 48 49 poker.add(temp); 50 } 51 } 52 53 poker.add(new Card("", "BlackJoker")); 54 poker.add(new Card("", "RedJoker")); 55 56 // System.out.println("一副牌:" + poker); 57 58 // 3、洗牌(考虑使用集合工具类Collections的shuffle方法) 59 Collections.shuffle((List<Card>)poker); 60 61 // System.out.println("洗一副牌:" + poker); 62 63 // 4、发牌 64 // 声明剩余底牌数量 65 int remain = 3; 66 67 // 声明三个玩家对象和一个底牌对象 68 Comparator<Card> comparator = new CardComparator(); 69 70 Set<Card> player1 = new TreeSet<>(comparator); 71 Set<Card> player2 = new TreeSet<>(comparator); 72 Set<Card> player3 = new TreeSet<>(comparator); 73 Set<Card> last = new TreeSet<>(comparator); 74 75 for (int i = 0; i < poker.size(); i++) { 76 if (i >= poker.size() - remain) { // 留下底牌 77 last.add(((List<Card>)poker).get(i)); 78 } else if (i % 3 == 0) { // 给第一个玩家发牌 79 player1.add(((List<Card>)poker).get(i)); 80 } else if (i % 3 == 1) { // 给第二个玩家发牌 81 player2.add(((List<Card>)poker).get(i)); 82 } else if (i % 3 == 2) { // 给第三个玩家发牌 83 player3.add(((List<Card>)poker).get(i)); 84 } 85 } 86 87 // 5、看牌 88 lookPoker("玩家1", player1); 89 lookPoker("玩家2", player2); 90 lookPoker("玩家3", player3); 91 lookPoker("底牌", last); 92 } 93 94 /** 95 * 看牌方法 96 * @param name 玩家名 97 * @param collection 手牌集合 98 */ 99 public static void lookPoker(String name, Set<Card> collection) { 100 System.out.println(name + "的手牌是:"); 101 for (Card item : collection) { 102 System.out.print(item + " "); 103 } 104 // 换行 105 System.out.println(); 106 } 107 }
1 package cn.temptation; 2 3 /** 4 * 牌类 5 */ 6 public class Card { 7 // 成员变量 8 // 花色 9 private String color; 10 // 数字 11 private String number; 12 13 // 构造函数 14 public Card() { 15 super(); 16 } 17 18 public Card(String color, String number) { 19 super(); 20 this.color = color; 21 this.number = number; 22 } 23 24 // 成员方法 25 public String getColor() { 26 return color; 27 } 28 29 public void setColor(String color) { 30 this.color = color; 31 } 32 33 public String getNumber() { 34 return number; 35 } 36 37 public void setNumber(String number) { 38 this.number = number; 39 } 40 41 @Override 42 public String toString() { 43 return color + number; 44 } 45 }
1 package cn.temptation; 2 3 import java.util.Comparator; 4 5 /** 6 * 牌的比较器 7 */ 8 public class CardComparator implements Comparator<Card> { 9 @Override 10 public int compare(Card card1, Card card2) { 11 // 首先比较数字 12 int resultNumber = numberChange(card1.getNumber()) - numberChange(card2.getNumber()); 13 14 // 数字相同时,比较花色 15 int result = (resultNumber == 0) ? colorChange(card1.getColor()) - colorChange(card2.getColor()) : resultNumber; 16 17 return result; 18 } 19 20 /** 21 * 手牌数字转换方法 22 * @param number 手牌数字 23 * @return 对应数字 24 */ 25 public static int numberChange(String number) { 26 int result = 0; 27 28 switch (number) { 29 case "J": 30 result = 11; 31 break; 32 case "Q": 33 result = 12; 34 break; 35 case "K": 36 result = 13; 37 break; 38 case "A": 39 result = 14; 40 break; 41 case "2": 42 result = 15; 43 break; 44 case "BlackJoker": 45 result = 16; 46 break; 47 case "RedJoker": 48 result = 17; 49 break; 50 default: 51 result = Integer.parseInt(number); 52 break; 53 } 54 55 return result; 56 } 57 58 /** 59 * 手牌花色转换方法 60 * @param color 手牌花色 61 * @return 对应数字 62 */ 63 public static int colorChange(String color) { 64 int result = 0; 65 66 switch (color) { 67 case "♥": 68 result = 1; 69 break; 70 case "♠": 71 result = 2; 72 break; 73 case "♣": 74 result = 3; 75 break; 76 case "◆": 77 result = 4; 78 break; 79 default: 80 break; 81 } 82 83 return result; 84 } 85 }
1 package cn.temptation; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.Collections; 6 import java.util.HashMap; 7 import java.util.List; 8 import java.util.Map; 9 import java.util.Set; 10 import java.util.TreeSet; 11 12 public class Sample17 { 13 public static void main(String[] args) { 14 // 需求:使用所学集合知识,模拟一副牌(54张)的洗牌、发牌(按照规则制作即可,规则选用一副牌斗地主)和看牌(有序) 15 // 牌:A、2、3、4、5、6、7、8、9、10、J、Q、K、BlackJoker、RedJoker 16 // 花色:♥ ◆ ♠ ♣ 17 // 顺序规则:牌的规则:3 < 4 < 5 < ... < 10 < J < Q < K < A < 2 < BlackJoker < RedJoker 18 // 花色的规则(牌相同时)♥ ♠ ♣ ◆ 19 20 // 思路2: 21 // 在发牌阶段进行排序比较麻烦,可以考虑在创建牌的时候,就把顺序订好,54张牌按照大小和花色有一个数字排序(索引) 22 // 后续操作时,洗牌洗的就是这个数字顺序,看牌时每个人的手牌和底牌都按数字顺序排列就好 23 24 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王),花色顺序和数字顺序都定好 25 // 2、牌不但有纸面内容(花色和数字),还有其索引,所以考虑使用Map存储 26 // 3、洗牌(考虑使用集合工具类Collections的shuffle方法) 27 // 4、发牌(发的也是牌的索引) 28 // 5、看牌 29 30 // 1、创建出一副牌54张(4种花色每种13张,还有大王小王),花色顺序和数字顺序都定好 31 // 创建花色集合 32 Collection<String> colors = new ArrayList<>(); 33 colors.add("♥"); 34 colors.add("♠"); 35 colors.add("♣"); 36 colors.add("◆"); 37 38 // 创建数字集合 39 Collection<String> numbers = new ArrayList<>(); 40 for (int i = 3; i <= 10; i++) { 41 numbers.add(String.valueOf(i)); 42 } 43 numbers.add("J"); 44 numbers.add("Q"); 45 numbers.add("K"); 46 numbers.add("A"); 47 numbers.add("2"); 48 49 // 2、牌不但有纸面内容(花色和数字),还有其索引,所以考虑使用Map存储 50 // 创建存放牌的容器 51 Map<Integer, String> poker = new HashMap<>(); 52 // 创建存放牌的索引的容器(伴随着把牌放入Map对象中,索引放入Collection对象中) 53 Collection<Integer> collection = new ArrayList<>(); 54 // 声明牌的索引变量 55 int index = 0; 56 57 // 注意:放牌进入map中顺序,先数字再花色 58 for (String number : numbers) { 59 for (String color : colors) { 60 // 把牌放入Map对象中 61 poker.put(index, color.concat(number)); 62 // 把牌的索引放入Collection对象中 63 collection.add(index); 64 // 创建一张牌,索引自增 65 index++; 66 } 67 } 68 69 // 创建小王 70 poker.put(index, "BlackJoker"); 71 collection.add(index); 72 index++; 73 74 // 创建大王 75 poker.put(index, "RedJoker"); 76 collection.add(index); 77 index++; 78 79 // 遍历map 80 // for (Entry<Integer, String> entry : poker.entrySet()) { 81 // System.out.println(entry.getKey() + "<----->" + entry.getValue()); 82 // } 83 84 // 3、洗牌(考虑使用集合工具类Collections的shuffle方法,洗的是牌的索引集合) 85 Collections.shuffle((List<Integer>)collection); 86 87 // System.out.println("洗一副牌:" + collection); 88 89 // 4、发牌(发的是牌的索引) 90 // 声明剩余底牌数量 91 int remain = 3; 92 93 Set<Integer> player1 = new TreeSet<>(); 94 Set<Integer> player2 = new TreeSet<>(); 95 Set<Integer> player3 = new TreeSet<>(); 96 Set<Integer> last = new TreeSet<>(); 97 98 for (int i = 0; i < poker.size(); i++) { 99 if (i >= poker.size() - remain) { // 留下底牌 100 last.add(((List<Integer>)collection).get(i)); 101 } else if (i % 3 == 0) { // 给第一个玩家发牌 102 player1.add(((List<Integer>)collection).get(i)); 103 } else if (i % 3 == 1) { // 给第二个玩家发牌 104 player2.add(((List<Integer>)collection).get(i)); 105 } else if (i % 3 == 2) { // 给第三个玩家发牌 106 player3.add(((List<Integer>)collection).get(i)); 107 } 108 } 109 110 // 5、看牌(根据键值对中的键去map中找值) 111 lookPoker("玩家1", player1, poker); 112 lookPoker("玩家2", player2, poker); 113 lookPoker("玩家3", player3, poker); 114 lookPoker("底牌", last, poker); 115 } 116 117 /** 118 * 看牌方法 119 * @param name 玩家名 120 * @param collection 手牌集合 121 */ 122 public static void lookPoker(String name, Set<Integer> collection, Map<Integer, String> map) { 123 System.out.println(name + "的手牌是:"); 124 125 for (Integer item : collection) { 126 System.out.print(map.get(item) + " "); 127 } 128 129 // 换行 130 System.out.println(); 131 } 132 }
1 package cn.temptation; 2 3 public class Sample18 { 4 public static void main(String[] args) { 5 /* 6 * 集合总结: 7 * Collection接口(单列集合): 8 * 1、List接口(有序、可重复): 9 * A、ArrayList:底层实现是数组,查找快速、增删比较慢 10 * B、Vector:向量类,ArrayList是其升级版,底层实现是数组,查找快速、增删比较慢,遍历向量对象可以使用枚举器(Enumeration) 11 * C、LinkedList:底层实现是链表,查找比较慢、增删快速 12 * 13 * 2、Set接口(无序、唯一): 14 * A、HashSet:底层实现是哈希表、依赖于hashCode()和equals() 15 * B、LinkedHashSet:底层实现是哈希表和链表组成,由哈希表保证元素唯一、由链表保证元素有序 16 * C、TreeSet:支持自然排序和自定义规则排序(实现Comparable接口 或 Comparator接口) 17 * 18 * Map接口(双列集合): 19 * A、HashMap:底层实现是哈希表、依赖于hashCode()和equals() 20 * B、LinkedHashMap:底层实现是哈希表和链表组成,由哈希表保证元素唯一、由链表保证元素有序 21 * C、TreeMap:支持自然排序和自定义规则排序(实现Comparable接口 或 Comparator接口) 22 * 23 * 24 * 是否需要键值对: 25 * 是:选择Map,键是否需要排序 26 * 是:选择TreeMap 27 * 否:选择HashMap 28 * 否:选择Collection,元素是否需要唯一 29 * 是:选择Set,元素是否需要排序 30 * 是:TreeSet 31 * 否:HashSet 32 * 否:选择List,需要查找快速还是需要增删快速 33 * 查找快速:ArrayList 34 * 增删快速:LinkedList 35 * 36 * 遍历元素: 37 * 1、一般for循环 38 * 2、迭代器(Iterator)或枚举器(Enumeration) 39 * 3、增强型for循环 40 * 41 */ 42 } 43 }