Day18_集合第四天

1、Map集合成员方法(掌握)



增加功能

V put(K key, V value)

当key在集合中不存在时,添加元素;当key在集合存在时候,替换元素

删除功能

void clear

清除所有键值对数据

V remove(Object key)

根据指定的键删除键值对

判断功能

boolean containsKey(Object key)

判断指定的键是否在集合中存在

boolean containsValue(Object value)

判断指定的值是否在集合中存在

boolean isEmpty

判断集合是否为空

获取功能

Set<Map.Entry<K,V>> entrySet()

键值对对象的集合

Object get(Object key)

根据键获取值

Set<K> keySet()

所有键的集合

Collection<V> values()

所有值的集合

长度

int size()

获取长度



2、Map集合的两种遍历方式(掌握)


创建

Map集合

  1. // 创建集合对象
  2. Map<String, String> map = new HashMap<String, String>();
  3. // 创建并添加元素
  4. map.put("杨过", "小龙女");
  5. map.put("郭靖", "黄蓉");
  6. map.put("梁山伯", "祝英台");
  7. map.put("牛郎", "织女");

第一种

遍历方式(通过keySet())

  1. Set<String> keySet = map.keySet();
  2. for(String key : keySet){
  3. System.out.println("key:"+key+" value"+map.get(key));
  4. }

第二种

遍历方式(通过entrySet())

当一个类或者一个接口被定义到类的成员位置的时候,在其他类中可以直接通过导入包名.外部类名.内部类名来使用。注意:这种方式只能创见引用,不能创建对象

package cn.itcast;
import cn.itcast.Outer.InnerClass;
public class Test {
    public static void main(String[] args) {
        InnerClass in = new Outer().new InnerClass();
        
    }
}
  1. Set<Entry<String,String>> entrySet = map.entrySet();
  2. for(Map.Entry<String, String> entry : entrySet){
  3. System.out.println("key"+entry.getKey()+"
  4. value"+entry.getValue());
  5. }




3、HashMap存储自定义对象实现去重 (将自定义对象存储到Key的位置)(掌握)

需求:需要将自定义对象存储到key的位置,并实现去重功能,怎么办?


解决方案1:使用HashMap(建议)
     自定义对象重写hashCode()和equals()方法,并且使用HashMap

解决方案2:使用TreeMap(详见)
     方案1:自定义对象实现Comparable 接口,并且重写compareTo方法
     方案2:创建TreeMap集合对象时通过TreeMap的构造方法传入一个Comparator对象


4、TreeMap存储自定义对象实现排序 (将自定义对象存储到Key的位置)(掌握)

1、方案1
     自定义对象实现Comparable 接口,并且重写compareTo方法

2、方案2
     创建TreeMap集合对象时通过TreeMap的构造方法传入一个Comparator对象


5、面试题:HashTable和HashMap区别(掌握)


Hashtable,ConCurrentHashMap
               线程安全,效率低,不允许null键和值
HashMap:
               线程不安全,效率高,允许null键和值

Hashtable和ConCurrentHashMap都是线程安全的,并且都不能存储null键和null值,ConCurrentHashMap效率更高,推荐在开发中面试中使用,Hashtable一般使用的比较少  

6、集合体系-总结(掌握)

注意:只有Vector和HashTable是线程安全的,效率低。


Collection(单列集合) Map(双列集合)
|--Collection(单列)
  |--List(有序,可重复)
          |--ArrayList
                         底层数据结构是数组,查询快,增删慢。
                         线程不安全,效率高。
          |--Vector
                         底层数据结构是数组,查询快,增删慢。
                         线程安全,效率低。
          |--LinkedList    
                         底层数据结构是链表,查询慢,增删快。
                         线程不安全,效率高。
  |--Set(可能无序,肯定唯一)
          |--HashSet
                         底层数据结构是哈希表。
                         线程不安全,效率高。

                         怎么保证唯一性的呢?
                         它依赖两个方法:hashCode()和equals()
                         顺序:
                              首先判断hashCode()值是否相同。
                              同:继续走equals(),看返回值
                                   如果true:就不添加到集合。
                                   如果false:就添加到集合。
                              不同:就添加到集合。
           |--TreeSet
                         底层数据结构是二叉树。
                         线程不安全,效率高。

                         怎么保证唯一性的呢?是根据返回是否是0。
                         怎么保证排序的呢?两种方式
                              自然排序(元素具备比较性)
                                   实现Comparable接口
                              比较器排序(集合具备比较性)
                                   实现Comparator接口
|--Map(双列 底层结构是针对键有效,跟值无关)
    |--HashMap
                    底层数据结构是哈希表。
                    线程不安全,效率高。允许null键和值

                    怎么保证唯一性的呢?
                    它依赖两个方法:hashCode()和equals()
                    顺序:
                         首先判断hashCode()值是否相同。
                         同:继续走equals(),看返回值
                              如果true:就不添加到集合。
                              如果false:就添加到集合。
                         不同:就添加到集合。
   |--Hashtable
                    底层数据结构是哈希表。
                    线程安全,效率低。不允许null键和值

                    怎么保证唯一性的呢?
                    它依赖两个方法:hashCode()和equals()
                    顺序:
                         首先判断hashCode()值是否相同。
                         同:继续走equals(),看返回值
                              如果true:就不添加到集合。
                              如果false:就添加到集合。
                         不同:就添加到集合。
   |--TreeMap
                    底层数据结构是二叉树。
                    线程不安全,效率高。

                    怎么保证唯一性的呢?是根据返回是否是0。
                    怎么保证排序的呢?两种方式
                         自然排序(元素具备比较性)
                              实现Comparable接口
                         比较器排序(集合具备比较性)
                              实现Comparator接口



7、案例(掌握)

1、HashMap集合键是Student值是String的案例

2、LinkedHashMap演示(LinkedHashMap特点:可以保证怎么存就怎么取)
3、TreeMap集合键是Student值是String的案例(按照姓名排序)
4、集合嵌套之HashMap嵌套HashMap
5、统计字符中每个字符出现的次数
6、模拟斗地主洗牌和发牌,牌没有排序(了解)
7、Collections案例演示


8、案例代码(掌握)

1、HashMap集合键是Student值是String的案例
  1. /**
  2. 学生类
  3. */
  4. public class Student implements Comparable<Student> {
  5. private String name;
  6. private int age;
  7. public Student() {
  8. super();
  9. }
  10. public Student(String name, int age) {
  11. super();
  12. this.name = name;
  13. this.age = age;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. public int getAge() {
  22. return age;
  23. }
  24. public void setAge(int age) {
  25. this.age = age;
  26. }
  27. @Override
  28. public String toString() {
  29. return "Student [name=" + name + ", age=" + age + "]";
  30. }
  31. @Override
  32. public int hashCode() {
  33. final int prime = 31;
  34. int result = 1;
  35. result = prime * result + age;
  36. result = prime * result + ((name == null) ? 0 : name.hashCode());
  37. return result;
  38. }
  39. @Override
  40. public boolean equals(Object obj) {
  41. if (this == obj)
  42. return true;
  43. if (obj == null)
  44. return false;
  45. if (getClass() != obj.getClass())
  46. return false;
  47. Student other = (Student) obj;
  48. if (age != other.age)
  49. return false;
  50. if (name == null) {
  51. if (other.name != null)
  52. return false;
  53. } else if (!name.equals(other.name))
  54. return false;
  55. return true;
  56. }
  57. @Override
  58. public int compareTo(Student o) {
  59. int num = this.age - o.age; //以年龄为主要条件
  60. return num == 0 ? this.name.compareTo(o.name) : num;
  61. }
  62. }
  63. /**
  64. 测试类
  65. */
  66. public class Demo5_HashMap {
  67. /*
  68. * * A:案例演示
  69. * HashMap集合键是Student值是String的案例
  70. * 键是学生对象,代表每一个学生
  71. * 值是字符串对象,代表学生归属地
  72. */
  73. public static void main(String[] args) {
  74. HashMap<Student, String> hm = new HashMap<>();
  75. hm.put(new Student("张三", 23), "北京");
  76. hm.put(new Student("张三", 23), "上海");
  77. hm.put(new Student("李四", 24), "广州");
  78. hm.put(new Student("王五", 25), "深圳");
  79. System.out.println(hm);
  80. }
  81. }
2、LinkedHashMap演示(LinkedHashMap特点:可以保证怎么存就怎么取)
  1. package com.heima.map;
  2. import java.util.LinkedHashMap;
  3. public class Demo6_LinkedHashMap {
  4. /**
  5. * @param args
  6. * LinkedHashMap可以保证怎么存就怎么取
  7. */
  8. public static void main(String[] args) {
  9. LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
  10. lhm.put("张三", 23);
  11. lhm.put("李四", 24);
  12. lhm.put("赵六", 26);
  13. lhm.put("王五", 25);
  14. System.out.println(lhm);
  15. }
  16. }

3、TreeMap集合键是Student值是String的案例(按照姓名排序)
  1. package com.heima.map;
  2. import java.util.Comparator;
  3. import java.util.TreeMap;
  4. import com.heima.bean.Student;
  5. public class Demo7_TreeMap {
  6. /**
  7. * * A:案例演示
  8. * TreeMap集合键是Student值是String的案例
  9. */
  10. public static void main(String[] args) {
  11. //demo1();
  12. TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
  13. @Override
  14. public int compare(Student s1, Student s2) {
  15. int num = s1.getName().compareTo(s2.getName()); //按照姓名比较
  16. return num == 0 ? s1.getAge() - s2.getAge() : num;
  17. }
  18. });
  19. tm.put(new Student("张三", 23), "北京");
  20. tm.put(new Student("李四", 13), "上海");
  21. tm.put(new Student("赵六", 43), "深圳");
  22. tm.put(new Student("王五", 33), "广州");
  23. System.out.println(tm);
  24. }
  25. public static void demo1() {
  26. TreeMap<Student, String> tm = new TreeMap<>();
  27. tm.put(new Student("张三", 23), "北京");
  28. tm.put(new Student("李四", 13), "上海");
  29. tm.put(new Student("王五", 33), "广州");
  30. tm.put(new Student("赵六", 43), "深圳");
  31. System.out.println(tm);
  32. }
  33. }

4、集合嵌套之HashMap嵌套HashMap
  1. package com.heima.map;
  2. import java.util.HashMap;
  3. import com.heima.bean.Student;
  4. public class Demo8_HashMapHashMap {
  5. /**
  6. * * A:案例演示
  7. * 集合嵌套之HashMap嵌套HashMap
  8. *
  9. * 需求:
  10. * 双元课堂有很多基础班
  11. * 第88期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
  12. * 第99期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
  13. *
  14. * 无论88期还是99期都是班级对象,所以为了便于统一管理,把这些班级对象添加到双元课堂集合中
  15. */
  16. public static void main(String[] args) {
  17. //定义88期基础班
  18. HashMap<Student, String> hm88 = new HashMap<>();
  19. hm88.put(new Student("张三", 23), "北京");
  20. hm88.put(new Student("李四", 24), "北京");
  21. hm88.put(new Student("王五", 25), "上海");
  22. hm88.put(new Student("赵六", 26), "广州");
  23. //定义99期基础班
  24. HashMap<Student, String> hm99 = new HashMap<>();
  25. hm99.put(new Student("唐僧", 1023), "北京");
  26. hm99.put(new Student("孙悟空",1024), "北京");
  27. hm99.put(new Student("猪八戒",1025), "上海");
  28. hm99.put(new Student("沙和尚",1026), "广州");
  29. //定义双元课堂
  30. HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
  31. hm.put(hm88, "第88期基础班");
  32. hm.put(hm99, "第99期基础班");
  33. //遍历双列集合
  34. for(HashMap<Student, String> h : hm.keySet()) { //hm.keySet()代表的是双列集合中键的集合
  35. String value = hm.get(h); //get(h)根据键对象获取值对象
  36. //遍历键的双列集合对象
  37. for(Student key : h.keySet()) { //h.keySet()获取集合总所有的学生键对象
  38. String value2 = h.get(key);
  39. System.out.println(key + "=" + value2 + "=" + value);
  40. }
  41. }
  42. }
  43. }


5、统计字符串中每个字符出现的次数
  1. package com.heima.test;
  2. import java.util.HashMap;
  3. public class Test1 {
  4. /**
  5. * * A:案例演示
  6. * 需求:统计字符串中每个字符出现的次数
  7. *
  8. * 分析:
  9. * 1,定义一个需要被统计字符的字符串
  10. * 2,将字符串转换为字符数组
  11. * 3,定义双列集合,存储字符串中字符以及字符出现的次数
  12. * 4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
  13. * 5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
  14. * 6,打印双列集合获取字符出现的次数
  15. */
  16. public static void main(String[] args) {
  17. //1,定义一个需要被统计字符的字符串
  18. String s = "aaaabbbbbccccccccccccc";
  19. //2,将字符串转换为字符数组
  20. char[] arr = s.toCharArray();
  21. //3,定义双列集合,存储字符串中字符以及字符出现的次数
  22. HashMap<Character, Integer> hm = new HashMap<>();
  23. //4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
  24. for(char c: arr) {
  25. //5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
  26. /*if(!hm.containsKey(c)) { //如果不包含这个键
  27. hm.put(c, 1);
  28. }else {
  29. hm.put(c, hm.get(c) + 1);
  30. }*/
  31. hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);
  32. }
  33. //6,打印双列集合获取字符出现的次数
  34. for (Character key : hm.keySet()) { //hm.keySet()代表所有键的集合
  35. System.out.println(key + "=" + hm.get(key));//hm.get(key)根据键获取值
  36. }
  37. }
  38. }

6、模拟斗地主洗牌和发牌,牌没有排序(了解)
  1. package com.heima.test;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.HashMap;
  5. import java.util.TreeSet;
  6. public class Test3 {
  7. /**
  8. * * A:案例演示
  9. * 模拟斗地主洗牌和发牌并对牌进行排序的代码实现
  10. *
  11. * 分析:
  12. * 1,买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
  13. * 2,洗牌
  14. * 3,发牌
  15. * 4,看牌
  16. */
  17. public static void main(String[] args) {
  18. //1,买一副扑克,其实就是自己创建一个集合对象,将扑克牌存储进去
  19. String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
  20. String[] color = {"红桃","黑桃","方片","梅花"};
  21. HashMap<Integer, String> hm = new HashMap<>(); //存储索引和扑克牌
  22. ArrayList<Integer> list = new ArrayList<>(); //存储索引
  23. int index = 0;
  24. //拼接扑克牌并索引和扑克牌存储在hm中
  25. for(String s1 : num) { //获取数字
  26. for(String s2 : color) { //获取颜色
  27. hm.put(index, s2.concat(s1));
  28. list.add(index); //将索引0到51添加到list集合中
  29. index++;
  30. }
  31. }
  32. //将小王添加到双列集合中
  33. hm.put(index, "小王");
  34. list.add(index); //将52索引添加到集合中
  35. index++;
  36. hm.put(index, "大王");
  37. list.add(index); //将52索引添加到集合中
  38. //2,洗牌
  39. Collections.shuffle(list);
  40. //3,发牌
  41. TreeSet<Integer> gaojin = new TreeSet<>();
  42. TreeSet<Integer> longwu = new TreeSet<>();
  43. TreeSet<Integer> me = new TreeSet<>();
  44. TreeSet<Integer> dipai = new TreeSet<>();
  45. for(int i = 0; i < list.size(); i++) {
  46. if(i >= list.size() - 3) {
  47. dipai.add(list.get(i)); //将三张底牌存储在底牌集合中
  48. }else if(i % 3 == 0) {
  49. gaojin.add(list.get(i));
  50. }else if(i % 3 == 1) {
  51. longwu.add(list.get(i));
  52. }else {
  53. me.add(list.get(i));
  54. }
  55. }
  56. //看牌
  57. lookPoker(hm, gaojin, "高进");
  58. lookPoker(hm, longwu, "龙五");
  59. lookPoker(hm, me, "冯佳");
  60. lookPoker(hm, dipai, "底牌");
  61. }
  62. /*
  63. * 看牌
  64. * 1,返回值类型void
  65. * 2,参数列表HashMap,TreeSet,String name
  66. */
  67. public static void lookPoker(HashMap<Integer, String> hm,TreeSet<Integer> ts ,String name) {
  68. System.out.print(name + "的牌是:");
  69. for(Integer i : ts) { //i代表双列集合中的每一个键
  70. System.out.print(hm.get(i) + " ");
  71. }
  72. System.out.println();
  73. }
  74. }


7、Collections案例演示
  1. package com.heima.collections;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. public class Demo1_Collecitons {
  5. /**
  6. * Collecitons中的常见方法
  7. * public static <T> void sort(List<T> list)
  8. public static <T> int binarySearch(List<?> list,T key)
  9. public static <T> T max(Collection<?> coll)
  10. public static void reverse(List<?> list)
  11. public static void shuffle(List<?> list)
  12. */
  13. public static void main(String[] args) {
  14. //demo1();
  15. //demo2();
  16. ArrayList<String> list = new ArrayList<>();
  17. list.add("a");
  18. list.add("c");
  19. list.add("d");
  20. list.add("g");
  21. list.add("f");
  22. //System.out.println(Collections.max(list)); //根据默认排序结果获取集合中的最大值
  23. //Collections.reverse(list); //反转集合
  24. Collections.shuffle(list); //随机置换,可以用来洗牌
  25. System.out.println(list);
  26. }
  27. public static void demo2() {
  28. ArrayList<String> list = new ArrayList<>();
  29. list.add("a");
  30. list.add("c");
  31. list.add("d");
  32. list.add("f");
  33. list.add("g");
  34. System.out.println(Collections.binarySearch(list, "c"));
  35. System.out.println(Collections.binarySearch(list, "b"));
  36. }
  37. public static void demo1() {
  38. ArrayList<String> list = new ArrayList<>();
  39. list.add("c");
  40. list.add("a");
  41. list.add("a");
  42. list.add("b");
  43. list.add("d");
  44. System.out.println(list);
  45. Collections.sort(list); //将集合排序
  46. System.out.println(list);
  47. }
  48. }



9、今天必须掌握的内容,面试题,笔试题。

1、HashMap中添加学生,姓名作为键,学生对象作为值,使用两种方式遍历
2、Hashtable和HashMap的区别
3、说说集合体系,最后那个大的总结背回
4、统计字符串中每个字符出现的次数
5、定义map<String,Integer>集合,集合中存储的元素:{"zhangsan",23}{"lisi",24}遍历集合中的元素,将key="张三"
6、有类似这样的字符串:"1.2,3.4,5.6,7.8,5.56,44.55,5.4"请按照要求,依次完成以下试题。
* (1)以逗号作为分隔符,把已知的字符串分成一个String类型的数组,数组中的每一个元素类似于"1.2","3.4"这样的字符串
* (2)把数组中的每一个元素以
* "."作为分隔符,把"."左边的元素作为key,右边的元素作为value,封装到Map中,Map中的key和value都是Object类型。
* (3)把map中的key封装的Set中,并把Set中的元素输出。
* (4)把map中的value封装到Collection中,把Collection中的元素输出。
上一篇:Windows内核读书笔记——Windows异常分发处理机制


下一篇:给phpcms v9加入一个主题radio无线电button,它可反复使用,以创建不同的专题部分内容编辑器,添加一个主题来定义自己的领域