• Day07 Stream流&递归&Map集合&Collections&可变参数


    Stream

            也叫Stream流,是Jdk8开始新增的一套API (java.util.stream.*),可以用于操作集合或者数组的数据。

           Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作

    1. public class Demo1 {
    2. public static void main(String[] args) {
    3. List list = new ArrayList<>();
    4. list.add("张无忌");
    5. list.add("周芷若");
    6. list.add("赵敏");
    7. list.add("张强");
    8. list.add("张三丰");
    9. //需求:把集合中所有以"张"开头,且是3个字的元素存储到一个新的集合。
    10. //实现2: 使用Stream流方式实现
    11. List list1 = list.stream().filter(name -> name.startsWith("张") ).
    12. filter(name -> name.length() == 3).collect(Collectors.toList());
    13. System.out.println(list1);
    14. }
    15. }

    Stream流的使用步骤 

    1.                                       2.                                              3.

                      

    如何获取Stream流 

    如何获取Stream流:
        Collection集合:
            单列集合都支持一个stream()方法,它可以直接获取集合的Stream流
        数组:
            Arrays.stream(数组)
        零散数据:
            Stream.of(T... values)
        Map
            双列集合并没有提供直接获取Stream流的方法,他需要间接获取
    
    1. public class Demo2 {
    2. public static void main(String[] args) {
    3. //"玄奘", "悟空", "悟能", "悟净"
    4. List list = List.of("玄奘", "悟空", "悟能", "悟净");
    5. //Collection集合: 单列集合都支持一个stream()方法,它可以直接获取集合的Stream流
    6. list.stream().forEach(System.out::println);
    7. //数组:Arrays.stream(数组)
    8. System.out.println("-------------------------------------");
    9. String[] arr = {"玄奘", "悟空", "悟能", "悟净"};
    10. Arrays.stream(arr).forEach(System.out::println);
    11. //零散数据:Stream.of(T... values)
    12. System.out.println("-------------------------------------");
    13. Stream.of("玄奘", "悟空", "悟能", "悟净").forEach(System.out::println);
    14. //Map:双列集合并没有提供直接获取Stream流的方法,他需要间接获取
    15. System.out.println("-------------------------------------");
    16. Map map = new HashMap<>();
    17. map.put("001","玄奘");
    18. map.put("002","悟空");
    19. map.put("003","悟能");
    20. map.put("004","悟净");
    21. //返回一个Set集合
    22. map.keySet().stream().forEach(System.out::println);
    23. map.values().stream().forEach(System.out::println);
    24. System.out.println("-------------------------------------");
    25. //这是一个整体EntrySetkeyvalue -> e
    26. map.entrySet().stream().forEach(e -> System.out.println(e.getValue() + e.getKey()));
    27. }
    28. }

    Stream流常见中间方法 

     

    1. public class Demo3 {
    2. public static void main(String[] args) {
    3. List list = List.of(61, 57, 66, 77, 88, 44, 100, 89, 97, 47, 70);
    4. //需求1: 找出所有及格的分数,并打印
    5. System.out.println("=================");
    6. list.stream()
    7. .filter(e -> e > 60)
    8. .forEach(System.out::println);
    9. //需求2: 找出所有及格的分数, 正序排列, 打印输出
    10. System.out.println("=================");
    11. list.stream()
    12. .filter(e -> e > 60)
    13. .sorted((o1, o2) -> o1 - o2)
    14. .forEach(System.out::println);
    15. //需求3: 找出所有及格的分数, 倒序排列, 打印输出
    16. System.out.println("=================");
    17. list.stream()
    18. .filter(e -> e > 60)
    19. .sorted((o1, o2) -> o2 - o1)
    20. .forEach(System.out::println);
    21. //需求4: 找出所有及格的分数, 倒序排列, 取前3名, 打印输出
    22. System.out.println("=================");
    23. list.stream().filter(e -> e > 60)
    24. .sorted((o1, o2) -> o2 - o1)
    25. .limit(3)
    26. .forEach(System.out::println);
    27. //需求5: 找出所有及格的分数, 倒序排列, 取前4-6名, 打印输出
    28. System.out.println("=================");
    29. list.stream().filter(e -> e > 60)
    30. .sorted((o1, o2) -> o2 - o1)
    31. .skip(3)
    32. .limit(3)
    33. .forEach(System.out::println);
    34. //需求6: 找出所有及格的分数, 倒序排列, 取前4-6名, 将每个人的分数加10分, 打印输出
    35. System.out.println("=================");
    36. list.stream().filter(e -> e > 60)
    37. .sorted((o1, o2) -> o2 - o1)
    38. .skip(3)
    39. .limit(3)
    40. .map(e -> e + 10)
    41. .forEach(System.out::println);
    42. //需求7: 将下面两个集合中的元素进行合并去重
    43. System.out.println("=================");
    44. List list1 = List.of("1","2","3","4");
    45. List list2 = List.of("1","5","7","4");
    46. Stream.concat(list1.stream(),list2.stream())
    47. .distinct()
    48. .forEach(System.out::println);
    49. }
    50. }

     Stream流常见终结方法

                         调用完成后,不会返回新Stream了,没法继续使用流了。 

     

    1. public class Demo4 {
    2. public static void main(String[] args) {
    3. List list = List.of(
    4. new Student("玄奘", 60, 165.5),
    5. new Student("悟空", 50, 175.5),
    6. new Student("悟能", 55, 145.5),
    7. new Student("悟净", 40, 185.5)
    8. );
    9. //1. 打印出集合中所有元素
    10. list.stream().forEach(System.out::println);
    11. //2. 统计出身高不足170的人数
    12. Stream stream = list.stream().filter(e -> e.getHeight() < 170);
    13. long count = stream.count();
    14. System.out.println(count);
    15. //3. 请找出年龄最大的对象, 并输出(了解)
    16. Student student = list.stream()
    17. .max((o1, o2) -> o1.getAge() - o2.getAge())
    18. .get();
    19. System.out.println(student);
    20. //4. 请找出身高最低的对象, 并输出(了解)
    21. Student student2 = list.stream()
    22. .min((o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight()))
    23. .get();
    24. System.out.println(student2);
    25. }
    26. }
    27. class Student {
    28. private String name;
    29. private int age;
    30. private double height;
    31. public Student() {
    32. }
    33. public Student(String name, int age, double height) {
    34. this.name = name;
    35. this.age = age;
    36. this.height = height;
    37. }
    38. public String getName() {
    39. return name;
    40. }
    41. public void setName(String name) {
    42. this.name = name;
    43. }
    44. public int getAge() {
    45. return age;
    46. }
    47. public void setAge(int age) {
    48. this.age = age;
    49. }
    50. public double getHeight() {
    51. return height;
    52. }
    53. public void setHeight(double height) {
    54. this.height = height;
    55. }
    56. @Override
    57. public String toString() {
    58. return "Student{" +
    59. "name='" + name + '\'' +
    60. ", age=" + age +
    61. ", height=" + height +
    62. '}';
    63. }
    64. }

     

    Stream流转数组/集合 

    1. public class Demo5 {
    2. public static void main(String[] args) {
    3. List list = List.of(
    4. new Teacher("玄奘", 60, 165.5),
    5. new Teacher("悟空", 50, 175.5),
    6. new Teacher("悟空", 50, 175.5),
    7. new Teacher("悟能", 55, 145.5),
    8. new Teacher("悟净", 40, 185.5));
    9. //1. 请找出身高超过170的教师, 并放到一个新数组中
    10. Object[] objects = list.stream()
    11. .filter(e -> e.getHeight() > 170)
    12. .toArray();
    13. System.out.println(Arrays.toString(objects));
    14. Teacher[] teacher = list.stream()
    15. .filter(e -> e.getHeight() > 170)
    16. //len代表元素中的个数
    17. .toArray(len -> new Teacher[len]);
    18. System.out.println(Arrays.toString(teacher));
    19. //2. 请找出身高超过170的教师, 并放到一个新List集合中
    20. List list1 = list.stream()
    21. .filter(e -> e.getHeight() > 170)
    22. .collect(Collectors.toList());
    23. System.out.println(list1);
    24. //3. 请找出身高超过170的教师, 并放到一个新Set集合中
    25. Set list2 = list.stream()
    26. .filter(e -> e.getHeight() > 170)
    27. .collect(Collectors.toSet());
    28. System.out.println(list2);
    29. //4. 请找出所有的教师的姓名和身高, 放到一个新Map集合中
    30. Map map = list.stream()
    31. .distinct()
    32. .collect(Collectors.toMap(e -> e.getName(), e-> e.getHeight()));
    33. System.out.println(map);
    34. }
    35. }
    36. class Teacher {
    37. private String name;
    38. private int age;
    39. private double height;
    40. public Teacher() {
    41. }
    42. public Teacher(String name, int age, double height) {
    43. this.name = name;
    44. this.age = age;
    45. this.height = height;
    46. }
    47. public String getName() {
    48. return name;
    49. }
    50. public void setName(String name) {
    51. this.name = name;
    52. }
    53. public int getAge() {
    54. return age;
    55. }
    56. public void setAge(int age) {
    57. this.age = age;
    58. }
    59. public double getHeight() {
    60. return height;
    61. }
    62. public void setHeight(double height) {
    63. this.height = height;
    64. }
    65. @Override
    66. public boolean equals(Object o) {
    67. if (this == o) return true;
    68. if (o == null || getClass() != o.getClass()) return false;
    69. Teacher teacher = (Teacher) o;
    70. return age == teacher.age && Double.compare(teacher.height, height) == 0 && Objects.equals(name, teacher.name);
    71. }
    72. @Override
    73. public int hashCode() {
    74. return Objects.hash(name, age, height);
    75. }
    76. @Override
    77. public String toString() {
    78. return "Teacher{" +
    79. "name='" + name + '\'' +
    80. ", age=" + age +
    81. ", height=" + height +
    82. '}';
    83. }
    84. }

    Map集合

    1.Map集合称为双列集合,一次需要存一对数据做为一个元素, 格式:{key1=value1 ,        key2=value2 , key3=value3 , ...}

    2.Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

    Map集合体系

     

    Map集合的实现类有哪些?各自的特点是? 

       1.HashMap: 无序,不重复

       2.LinkedHashMap: 有序,不重复

       3.TreeMap:排序,不重复 

     Map接口常用方法

     

    Map集合三种遍历方式 

    1. public class Demo2 {
    2. public static void main(String[] args) {
    3. //1. 创建map
    4. HashMap map = new HashMap<>();
    5. map.put("001", "玄奘");
    6. map.put("002", "悟空");
    7. map.put("003", "悟能");
    8. map.put("004", "悟净");
    9. //2. 各种方式进行遍历
    10. test1(map);
    11. System.out.println("=================");
    12. test2(map);
    13. System.out.println("=================");
    14. test3(map);
    15. }
    16. //遍历方式1: 先获取Map集合全部的键,再通过遍历键来找值
    17. private static void test1(HashMap map) {
    18. Set set = map.keySet();
    19. for (String s : set) {
    20. System.out.println(s + map.get(s));
    21. }
    22. }
    23. //遍历方式2: 将map中的所有键值对放入一个set集合中, 然后遍历set集合拿到每个键值对, 再取里面的键值
    24. private static void test2(HashMap map) {
    25. Set> entries = map.entrySet();
    26. for (Map.Entry entry : entries) {
    27. System.out.println(entry.getKey() + entry.getValue());
    28. }
    29. }
    30. //遍历方式3: Lambda, 使用foreach(BiConsumer bc)
    31. private static void test3(HashMap map) {
    32. map.forEach((k,v) -> System.out.println(k+v));
    33. }
    34. }

    Map集合案例 

     

    现有字符串数组如下:
        String[] bookArr = {"《红楼梦》-曹雪芹","《西游记》-吴承恩","《三国演义》-罗贯中","《水浒传》-施耐庵"};
    需求:
        请将字符串中的书名提取为Map集合的键,将作者提取为Map集合的值
        并使用三种不同方式,遍历Map集合打印键值对元素内容
    1. public class Demo3 {
    2. public static void main(String[] args) {
    3. Map map = new HashMap<>();
    4. String[] bookArr = {"《红楼梦》-曹雪芹","《西游记》-吴承恩","《三国演义》-罗贯中","《水浒传》-施耐庵"};
    5. for (String book : bookArr) {
    6. String[] split = book.split("-");
    7. map.put(split[0],split[1] );
    8. }
    9. System.out.println(map);
    10. Set set = map.keySet();
    11. for (String key : set) {
    12. System.out.println(key + map.get(key));
    13. }
    14. System.out.println("----------------------------");
    15. Set> entries = map.entrySet();
    16. for (Map.Entry entry : entries) {
    17. System.out.println(entry.getKey()+entry.getValue());
    18. }
    19. System.out.println("----------------------------");
    20. map.forEach((key , value) -> System.out.println(key+value));
    21. }
    22. }

     HashMap底层原理

          和HashSet一样 :Day06List接口&Set接口&树-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_60388241/article/details/133930070?spm=1001.2014.3001.5501

    LinkedHashMap

    底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)。 

    TreeMap 

    1. public class Demo6 {
    2. private String put;
    3. public static void main(String[] args) {
    4. //创建集合
    5. Map map = new TreeMap<>((o1, o2) -> o1.getAge() - o2.getAge());
    6. map.put(new Teacher("张三", 21), "河北");
    7. map.put(new Teacher("李四", 20), "山东");
    8. map.put(new Teacher("王五", 19), "山西");
    9. map.put(new Teacher("赵六", 21), "河南");
    10. map.forEach((k, v) -> {
    11. System.out.println(k + "-----" + v);
    12. });
    13. }
    14. }
    15. class Teacher {
    16. private String name;
    17. private int age;
    18. public Teacher() {
    19. }
    20. public Teacher(String name, int age) {
    21. this.name = name;
    22. this.age = age;
    23. }
    24. public String getName() {
    25. return name;
    26. }
    27. public void setName(String name) {
    28. this.name = name;
    29. }
    30. public int getAge() {
    31. return age;
    32. }
    33. public void setAge(int age) {
    34. this.age = age;
    35. }
    36. @Override
    37. public String toString() {
    38. return "Teacher{" +
    39. "name='" + name + '\'' +
    40. ", age=" + age +
    41. '}';
    42. }
    43. }

     集合的嵌套

    集合嵌套
        要求在程序中记住如下省份和其对应的城市信息,记录成功后,要求可以查询出湖北省的城市信息。
    
    数据
        江苏省 = "南京市","扬州市","苏州市","无锡市","常州市"
        湖北省 = "武汉市","孝感市","十堰市","宜昌市","鄂州市"
        河北省 = "石家庄市","唐山市","邢台市","保定市","张家口市"
    
    分析:
        定义一个Map集合,键用表示省份名称,值表示城市名称,注意:城市会有多个。 Map>
        根据“湖北省”这个键获取对应的值展示即可。
    
    1. public class Demo7 {
    2. public static void main(String[] args) {
    3. Map> map = new HashMap<>();
    4. List list = List.of("南京市","扬州市","苏州市","无锡市","常州市");
    5. List list2 = List.of("石家庄市","唐山市","邢台市","保定市","张家口市");
    6. map.put("江苏省",list);
    7. map.put("河北省",list2);
    8. System.out.println(map);
    9. }
    10. }

     Collections

      可变参数 

    可变参数
        就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型... 参数名称
    
    优点
        特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。
        好处:常常用来灵活的接收数据。
    
    注意事项
        1. 可变参数在方法内部就是一个数组
        2. 一个形参列表中可变参数只能有一个
        3. 可变参数必须放在形参列表的最后面
    
    1. public class Demo {
    2. public static void main(String[] args) {
    3. sum(1546);
    4. }
    5. //计算2个整数的和
    6. //计算3个整数的和
    7. //计算4个整数的和
    8. //计算n个整数的和
    9. public static void sum(int... a){
    10. for (int i : a) {
    11. System.out.println(i);
    12. }
    13. }
    14. }

     Collections工具类

     

    1. public class Demo {
    2. public static void main(String[] args) {
    3. List list = new ArrayList<>();
    4. //static boolean addAll(单列集合,可变参数) 批量添加元素
    5. Collections.addAll(list,1,2,100,3,45);
    6. System.out.println(list);
    7. //static void shuffle(List集合) 打乱List集合元素顺序,每次调用都会打乱
    8. Collections.shuffle(list);
    9. System.out.println(list);
    10. //static void sort(List集合) List集合进行自然排序
    11. Collections.sort(list);
    12. System.out.println(list);
    13. //排自定义类对象,需要指定排序规则
    14. List stuList = new ArrayList<>();
    15. stuList.add(new Student("zhangsan", 18));
    16. stuList.add(new Student("wangwu", 22));
    17. stuList.add(new Student("zhaoliu", 21));
    18. stuList.add(new Student("lisi", 19));
    19. stuList.add(new Student("qianqi", 20));
    20. //static void sort(List集合,比较器);List集合进行比较器排序
    21. Collections.sort(stuList,(o1, o2) -> o1.getAge() - o2.getAge());
    22. System.out.println(stuList);
    23. }
    24. }
    25. class Student {
    26. private String name;
    27. private int age;
    28. public Student() {
    29. }
    30. public Student(String name, int age) {
    31. this.name = name;
    32. this.age = age;
    33. }
    34. public String getName() {
    35. return name;
    36. }
    37. public void setName(String name) {
    38. this.name = name;
    39. }
    40. public int getAge() {
    41. return age;
    42. }
    43. public void setAge(int age) {
    44. this.age = age;
    45. }
    46. @Override
    47. public String toString() {
    48. return "Student{" +
    49. "name='" + name + '\'' +
    50. ", age=" + age +
    51. '}';
    52. }
    53. }

     

     

     

     

     

  • 相关阅读:
    Linux云服务器安装mail邮件服务
    分布式事务解决方案
    Asp.Net Core6.0中MediatR的应用CQRS
    Selenium获取百度百科旅游景点的InfoBox消息盒
    C语言关于自定义字符函数和字符串函数的相关笔试题(找工作必看)
    Spring官宣网传大漏洞,并提供解决方案
    Hyperledger Fabric组织的动态添加和删除
    让技术文档网站看起来更专业
    【深度学习】大模型卷到机器人上了
    浅谈spring的@Scheduled定时任务(演示)
  • 原文地址:https://blog.csdn.net/m0_60388241/article/details/133965111