一.Map集合 1.1 Map的概述以及特点 什么是Map集合: Collection集合称为单列集合,Map集合称为双列集合,key-value,键-值,名称:Entry Map集合的特点: a.Collection每个元素单独存在(单列),Map每个元素成对存在(双列) b.Map集合中,键必须是唯一的,值是可以重复的 c.Collection中,泛型只有一个。Map<K,V>中,泛型有两个(其中K代表键Key的类,V代表值Value类)
1.2 Map的3个常用实现类以及其特点 Map接口有三个常见的实现类: HashMap<K,V>: 底层采用哈希表结构 无序
LinkedHashMap<K,V>: 底层采用链表+哈希表结构 有序
TreeMap<K,V>: 底层采用红黑树结构 无序,键有自然顺序的,即按照键的自然顺序输出
重点:Map中为了保证键的唯一性,如果键是自定义类型,必须重写键的hashCode和equals方法
1.3 Map接口中定义的通用方法 增:public V put(K key, V value) ;添加一个键值对Entry,返回null 删:public V remove(Object key);根据键Key去删键值对Entry,返回被删除的键值对的值 查:public V get(Object key);根据键Key获取对应的值Value 改:public V put(K key, V value) ;添加一个重复的键时,该方法变为修改,返回修改前的值 其他: public boolean containKey(Object K);判断Map中是否包含该键 public boolean containKey(Object V);判断Map中是否包含该值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public static void main (String[] args) { HashMap<String ,Integer> map = new HashMap <String,Integer>(); map.put("a" ,1 ); map.put("b" ,2 ); map.put("c" ,3 ); map.put("d" ,4 ); map.put("e" ,5 ); map.put("f" ,6 ); System.out.println(map); Integer v1 = map.remove("a" ); System.out.println(v1); System.out.println(map); Integer v2 = map.remove("g" ); System.out.println(v2); System.out.println(map); Integer v3 = map.get("a" ); System.out.println(v3); System.out.println(map); Integer v4 = map.put("c" , 12 ); System.out.println(v4); System.out.println(map); boolean k = map.containsKey("a" ); System.out.println(k); boolean v = map.containsValue(5 ); System.out.println(v); }
1.4 Map的遍历 •遍历方式一:以键找值 public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static void main (String[] args) { HashMap<String, Integer> map = new HashMap <String, Integer>(); map.put("a" , 1 ); map.put("b" , 2 ); map.put("c" , 3 ); map.put("d" , 4 ); map.put("e" , 5 ); map.put("f" , 6 ); Set<String> keys = map.keySet(); for (String key : keys) { Integer value = map.get(key); System.out.println(key); System.out.println(value); } }
•遍历方式二:键值对方式 public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static void main (String[] args) { HashMap<String, Integer> map = new HashMap <String, Integer>(); map.put("a" , 1 ); map.put("b" , 2 ); map.put("c" , 3 ); map.put("d" , 4 ); map.put("e" , 5 ); map.put("f" , 6 ); Set<Map.Entry<String, Integer>> entries = map.entrySet(); for (Map.Entry<String, Integer> entry : entries) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+"..." +value); } }
1.5 HashMap存储自定义类型的键 需求:创建一个Map,学生为键,家庭地址作值。
学生键:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Student { String Name; int age; public Student () { } @Override public String toString () { return "Student{" + "Name='" + Name + '\'' + ", age=" + age + '}' ; } public Student (String name, int age) { Name = name; this .age = age; } @Override public boolean equals (Object o) { if (this == o) { return true ; } if (o == null || getClass() != o.getClass()) { return false ; } Student student = (Student) o; return age == student.age && Objects.equals(Name, student.Name); } @Override public int hashCode () { return Objects.hash(Name, age); } }
测试Demo:
1 2 3 4 5 6 7 8 9 10 11 public static void main (String[] args) { HashMap<Student,String > std= new HashMap <Student,String>(); std.put(new Student ("a" ,1 ), "PK" ); std.put(new Student ("b" ,2 ), "GZ" ); std.put(new Student ("c" ,3 ), "SH" ); std.put(new Student ("d" ,4 ), "SZ" ); System.out.println(std); std.put(new Student ("b" ,2 ), "SC" ); System.out.println(std); }
结论:如果键是自定义类型,那么为了保证键的唯一性,必须重写hashCode和equals方法
1.6 LinkedHashMap介绍 HashMap底层采用哈希表结构,所以无序 LinkedHashMap底层采用的是链表结构+哈希表,所以是有序的
1 2 3 4 5 6 7 8 9 public static void main (String[] args) { LinkedHashMap<String ,Integer> LHS = new LinkedHashMap <String ,Integer>(); LHS.put("a" , 1 ); LHS.put("c" , 1 ); LHS.put("d" , 1 ); LHS.put("b" , 1 ); System.out.println(LHS); }
1.7 TreeMap集合 TreeMap底层采用的是红黑树结构,无序的,但是会以键的自然顺序输出
1 2 3 4 5 6 7 8 9 10 public static void main (String[] args) { TreeMap<String ,Integer> TM = new TreeMap <String,Integer>(); TM.put("a" , 1 ); TM.put("c" , 2 ); TM.put("e" , 3 ); TM.put("d" , 4 ); TM.put("b" , 5 ); System.out.println(TM); }
扩展: 如果键是数值类型,那么按照数值的大小升序 如果键是Character类型,那么按照字母的码值排序 如果键是String类型,那么按照字母首字母排序,若一样,次字母排序,依次类推 这四种结论是一样的:Arrays.sort() Collections.sort() TreeSet TreeMap
我们也可以使用比较器排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public static void main (String[] args) { TreeMap<String, Integer> TM = new TreeMap <String, Integer>(); TM.put("a" , 1 ); TM.put("c" , 2 ); TM.put("e" , 3 ); TM.put("d" , 4 ); TM.put("b" , 5 ); System.out.println(TM); TreeMap<Integer, String> new_TM = new TreeMap <Integer, String>(new Comparator <Integer>() { @Override public int compare (Integer o1, Integer o2) { return o2 - o1; } }); new_TM.put(1 , "a" ); new_TM.put(3 , "a" ); new_TM.put(2 , "a" ); new_TM.put(5 , "a" ); new_TM.put(4 , "a" ); System.out.println(new_TM); TreeMap<Student, String> std = new TreeMap <Student, String>(new Comparator <Student>() { @Override public int compare (Student o1, Student o2) { return o2.Name.length() - o1.Name.length(); } }); std.put(new Student ("aa" , 1 ), "PK" ); std.put(new Student ("bbb" , 2 ), "GZ" ); std.put(new Student ("cc" , 3 ), "SH" ); std.put(new Student ("ddddd" , 4 ), "SZ" ); System.out.println(std); }
1.8 Map集合练习 输入一个字符串,统计字符串中每个字符出现的次数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static void main (String[] args) { LinkedHashMap<Character, Integer> LHM = new LinkedHashMap <Character, Integer>(); System.out.println("input char" ); String str = new Scanner (System.in).nextLine(); for (int i = 0 ; i < str.length(); i++) { char ch = str.charAt(i); if (LHM.containsKey(ch)) { Integer oldCount = LHM.get(ch); LHM.put(ch, oldCount + 1 ); } else { LHM.put(ch, 1 ); } } System.out.println(LHM); }
二.集合的嵌套 什么是集合嵌套 集合中的元素还是一个集合
2.1 List嵌套list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static void main (String[] args) { ArrayList<String> class1 = new ArrayList <String>(); Collections.addAll(class1, "a" , "b" , "c" ); ArrayList<String> class2 = new ArrayList <String>(); Collections.addAll(class2, "e" , "f" , "g" ); ArrayList<ArrayList<String>> classAll = new ArrayList <ArrayList<String>>(); Collections.addAll(classAll, class1, class2); for (ArrayList<String> className : classAll) { for (String name:className ) { System.out.println(name); } System.out.println(className); } }
2.2 List嵌套Map a.保存两个班学生的姓名以及对应的年龄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public static void main (String[] args) { HashMap<String, Integer> class1 = new HashMap <String, Integer>(); class1.put("a" , 12 ); class1.put("b" , 11 ); class1.put("c" , 13 ); class1.put("d" , 14 ); class1.put("e" , 18 ); HashMap<String, Integer> class2 = new HashMap <String, Integer>(); class2.put("f" , 19 ); class2.put("g" , 17 ); class2.put("h" , 16 ); class2.put("i" , 15 ); class2.put("k" , 14 ); ArrayList<HashMap<String, Integer>> classAll = new ArrayList <HashMap<String, Integer>>(); classAll.add(class1); classAll.add(class2); System.out.println(classAll); for (HashMap<String, Integer> className : classAll ) { Set<String> keys = className.keySet(); for (String key : keys) { System.out.println(key); } System.out.println(className); } }
2.3 Map嵌套Map a.保存两个班的名字,和班里的同学的姓名,以及对应的年龄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public static void main (String[] args) { HashMap<String, Integer> class1 = new HashMap <String, Integer>(); class1.put("a" , 12 ); class1.put("b" , 11 ); class1.put("c" , 13 ); class1.put("d" , 14 ); class1.put("e" , 18 ); HashMap<String, Integer> class2 = new HashMap <String, Integer>(); class2.put("f" , 19 ); class2.put("g" , 17 ); class2.put("h" , 16 ); class2.put("i" , 15 ); class2.put("k" , 14 ); HashMap<String, HashMap<String, Integer>> classAll = new HashMap <String, HashMap<String, Integer>>(); classAll.put("class one" , class1); classAll.put("class two" , class2); System.out.println(classAll); Set<String> names = classAll.keySet(); System.out.println(names); for (String name : names) { HashMap<String, Integer> map = classAll.get(name); System.out.println(map); Set<String> ns = map.keySet(); for (String n : ns ) { Integer value = map.get(n); System.out.println(n + "..." + value); } } }
.模拟斗地主洗牌发牌 3.1 案例介绍 3.2 案例分析 斗地主要想办法自定义排序规则 核心思想:给斗地主中每一张牌,准备一个编号 a.不能出现相同的编号 b.牌越大,编号越大
I.准备编号和牌组成的Map集合 II.准备54个编号(一副牌) III.洗牌(打乱集合) V.发牌(遍历集合) IV.对编号排序(sort) IIV.转牌(以键找值map.get) IIIV.打印给用户(println)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 public static void main (String[] args) { LinkedHashMap<Integer, String> Map = new LinkedHashMap <Integer, String>(); String[] colors = {"黑桃♠️" , "红桃♥️" , "梅花♣️" , "方片♦️" }; String[] numbers = {"3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "K" , "Q" , "A" , "2" }; int id = 1 ; for (String num : numbers) { for (String color : colors) { String card = color + num; Map.put(id, card); id++; } } Map.put(53 , "小王" ); Map.put(54 , "大王" ); ArrayList<Integer> Cards = new ArrayList <Integer>(); for (int i = 1 ; i < 55 ; i++) { Cards.add(i); } Collections.shuffle(Cards); ArrayList<Integer> player1 = new ArrayList <Integer>(); ArrayList<Integer> player2 = new ArrayList <Integer>(); ArrayList<Integer> player3 = new ArrayList <Integer>(); ArrayList<Integer> Holo_Card = new ArrayList <Integer>(); for (int i = 0 ; i < Cards.size()-3 ; i++) { Integer Card = Cards.get(i); if (i % 3 == 0 ) { player1.add(Card); } else if (i % 3 == 1 ) { player2.add(Card); } else { player3.add(Card); } } Holo_Card.add(Cards.get(53 )); Holo_Card.add(Cards.get(52 )); Holo_Card.add(Cards.get(51 )); Collections.sort(player1); Collections.sort(player2); Collections.sort(player3); Collections.sort(Holo_Card); lookCards(player1, Map); lookCards(player2, Map); lookCards(player3, Map); lookCards(Holo_Card, Map); } public static void lookCards (ArrayList<Integer> idCards, LinkedHashMap<Integer, String> Map) { for (Integer idCard : idCards) { String card = Map.get(idCard); System.out.println(card + "" ); } System.out.println(); }
3.3 代码实现
三.冒泡排序 排序:将一组数据按照固定的规则进行排列
3.1 冒泡排序的介绍 所谓的冒泡排序的思想: 依次比较数组/集合中相连的两个元素,然后将较大的元素放在后面,最后按照从小到大的顺序排列出来 规律: •如果有n个数进行排序比较,那么比较次数为n-1轮 •每轮比较完毕,下一轮比较就会少一个数据参与
4.2 冒泡排序过程图解
3.3 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void main (String[] args) { int [] arr = {4 , 6 , 1 , 3 , 82 , 9 , 7 , 5 }; for (int i = 0 ; i < arr.length - 1 ; i++) { for (int j = 0 ; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1 ]) { int temp = arr[j]; arr[j] = arr[j + 1 ]; arr[j + 1 ] = temp; } } } System.out.println(Arrays.toString(arr)); }
总结: 1.Map接口中定义对通用方法* put(K,V); remove(K); get(K) put(repeat K,V) containsKey(K) containsValue(V)
2.Map各种实现类对遍历方式(以键找值,键值对)* a.以键找值 set keys = map.kepSet(); for(K key:keys){//遍历所有的键 //以键找值 V value = map.get(key); sout(key,value); }
b.键值对 set<Map.Entry<K,V>> entrys = map.entrySet();//获取所有的键值对集合 for(Map.Entry<K,V> entry:entrys)//遍历键值对集合 { K key = entry.getKey();//获取键值中对键和值 V value = entry.getValue();//获取键值中对键和值 sout(key,value); } 3.集合嵌套 a.List套list ArrayList arr;
b.List套Map ArrayList<HashMap<String,Integet>> arr;
c.Map套map HashMap<String,HashMap<String,Integer>> map;
4.斗地主案例*
5.冒泡排序 a.冒泡过程 b.算法背下来
1 2 3 4 5 6 7 8 for (int i=0 ;i<arr.lenth-1 ;i++){ for (int j=0 ;j<arr.lenth-1 -i;j++){ if (arr[j]>arr[j+i]){ int temp=arr[j]; arr[j]=arr[j+1 ] arr[j+1 ]=temp; }} }