• Java#31(不可变集合,Stream流和方法引用)


    目录

    一.创建不可变集合: 不可以被修改的集合

    1.List接口创建不可变集合

    2.Set接口创建不可变集合

    3.Map接口创建不可变集合

    二.Stream流

    1.如何获取Stream流?

    2.Stream流的中间方法

    3.Stream流终结方法

    三.方法引用

    1.引用静态方法

    2.引用成员方法

    3.引用结构方法

    4.使用类名引用成员方法

    5.引用数组的构造方法


    一.创建不可变集合: 不可以被修改的集合

    作用: 不让别人修改集合中的内容

    1.List接口创建不可变集合

    格式: List.of(数据); 

    可以进行查询和遍历但是不能修改内容

    代码示范:

    1. package Demo;
    2. import java.util.List;
    3. import java.util.Locale;
    4. import java.util.function.Consumer;
    5. public class Test1 {
    6. public static void main(String[] args) {
    7. List list = List.of("张三", "李四", "王五");
    8. System.out.println(list.get(0));
    9. System.out.println(list.get(1));
    10. System.out.println(list.get(2));
    11. System.out.println("-----------------------");
    12. //遍历
    13. for (String s : list) {
    14. System.out.println(s);
    15. }
    16. System.out.println("------------------------");
    17. list.forEach(s-> System.out.println(s));
    18. list.add("maliu");
    19. }
    20. }

     (未对集合内容进行更改)

     (想修改集合内容就会报错)

    2.Set接口创建不可变集合

    格式: Set.of(数据);

    可以进行查询和遍历但是不能修改内容(元素不能出现重复)

    3.Map接口创建不可变集合

    可以进行查询和遍历但是不能修改内容(元素不能出现重复)

    格式: Map.of(数据); (键值对数量最多是10个)

             Map.copyOf(Map集合); (没有键值对数量限制, 在JDK10开始出现)

    (Map.of()添加10个键值对,没有报错) 

     (Map.of()添加11个键值对,直接报错) 

    Map.copyOf(Map集合); 的代码示范:

    1. import java.util.HashMap;
    2. import java.util.Map;
    3. import java.util.function.BiConsumer;
    4. public class Test3 {
    5. public static void main(String[] args) {
    6. Map map1 = new HashMap();
    7. map1.put("1","a");
    8. map1.put("2","a");
    9. map1.put("3","a");
    10. map1.put("4","a");
    11. map1.put("5","a");
    12. map1.put("6","a");
    13. map1.put("7","a");
    14. map1.put("8","a");
    15. map1.put("9","a");
    16. map1.put("10","a");
    17. map1.put("11","a");
    18. map1.put("12","a");
    19. Map map2 = Map.copyOf(map1);
    20. map2.forEach((s, s2)-> System.out.println(s+"="+s2));
    21. //map2.put("13","a");
    22. }
    23. }

    结果展示: 

    二.Stream流

    作用: 结合了lambda表达式,简化集合,数组的操作

    步骤:

    (1)先得到一条Stream流,并把数据放上去

    (2)利用Stream流中的API进行各种操作(过滤,转换(中间方法: 方法调用后还可以调用其他方法), 统计, 打印(终结方法: 最后一步, 调用完毕之后, 不能调用其他方法))

    1.如何获取Stream流?

    获取方式                                        方法名                                                       说明
    单列集合                       default Stream stream0                      Collection中的默认方法
    双列集合                                            无                                          无法直接使用stream流
    数组              public static Stream stream(T[ ] array)  Arrays工具类中的静态方法
    一堆零散数据      public static Stream of(T... values)       stream接口中的静态方法

    单列集合获取Stream流代码示范:

    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. public class StreamDemo1 {
    4. public static void main(String[] args) {
    5. ArrayList arr = new ArrayList<>();
    6. Collections.addAll(arr,"b","c","a");
    7. arr.stream().forEach(s -> System.out.println(s));//遍历集合
    8. }
    9. }

    结果展示:

     双列集合获取Stream流代码示范:

    1. import java.util.HashMap;
    2. public class StreamDemo2 {
    3. public static void main(String[] args) {
    4. HashMap map = new HashMap<>();
    5. map.put("a",1);
    6. map.put("b",2);
    7. map.put("c",3);
    8. //第一种方式
    9. map.keySet().forEach(s -> System.out.println(s));
    10. System.out.println("---------------------------");
    11. //第二种方式
    12. map.entrySet().forEach(a-> System.out.println(a));
    13. }
    14. }

    结果展示:

    数组获取Stream流代码示范:

    1. import java.util.Arrays;
    2. public class StreamDemo3 {
    3. public static void main(String[] args) {
    4. int[] arr = {1,2,3,4,5,6,7};
    5. Arrays.stream(arr).forEach(i-> System.out.println(i));
    6. }
    7. }

    结果展示:

     一堆零散数据获取Stream流代码示范:

    1. import java.util.stream.Stream;
    2. public class StreamDemo4 {
    3. public static void main(String[] args) {
    4. Stream.of(1,2,3,4,5).forEach(i-> System.out.print(i+" "));
    5. System.out.println();
    6. System.out.println("-----------------");
    7. Stream.of("a","b","c").forEach(s-> System.out.print(s+" "));
    8. String[] s = {"a","b","c","d"};
    9. Stream.of(s).forEach(a-> System.out.print(a+" "));
    10. System.out.println();
    11. int[] arr1 = {1,2,3,4,5,6};
    12. Stream.of(arr1).forEach(i-> System.out.print(i+" "));
    13. }
    14. }

    结果展示:

    注意: Stream.of()   ()中添加元素是类型要相同, 添加数组时只能添加引用数据类型,如果添加基本数据类型打印的是地址

    2.Stream流的中间方法

                         名称                                                                       说明
    Stream filter(Predicate predicate)                过滤
    Stream limit(long maxSize)                                       获取前几个元素
    Stream skip(long n)                                                   跳过前几个元素
    Stream distinct()                                    元素去重,依赖(hashCode和equals方法)
    static Stream concat(Stream a, Stream b)    合并a和b两个流为一个流

    Stream map(Function mapper)                    转换流中的数据类型
    注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,所以没有必要创建一个新的变量来存储, 建议使用链式编程

    注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据

    代码示范:

    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. import java.util.function.Function;
    4. import java.util.function.Predicate;
    5. import java.util.stream.Stream;
    6. public class StreamDemo5 {
    7. public static void main(String[] args) {
    8. ArrayList list = new ArrayList<>();
    9. Collections.addAll(list,"小明","小红","小李飞刀","小张","刘备","马超","黄忠");
    10. //1.filter
    11. list.stream().
    12. /*filter(new Predicate() {
    13. @Override
    14. public boolean test(String s) {
    15. return s.startsWith("小");
    16. }
    17. })*/
    18. filter(s-> s.startsWith("小"))//true表示留下, false表示舍弃
    19. .forEach(s-> System.out.println(s));
    20. System.out.println("======================");
    21. //2.limit
    22. list.stream()
    23. .limit(3)
    24. .forEach(s-> System.out.println(s));
    25. System.out.println("======================");
    26. //3.skip
    27. list.stream()
    28. .skip(2)
    29. .forEach(s -> System.out.println(s));
    30. System.out.println("======================");
    31. //4.distinct
    32. ArrayList list2 = new ArrayList<>();
    33. Collections.addAll(list2,"李华","王五");
    34. Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));
    35. System.out.println("======================");
    36. //5.map
    37. ArrayList list3 = new ArrayList<>();
    38. Collections.addAll(list3,"小华-12","小五-13","马六-14");
    39. //第一个是原本的数据类型,
    40. //第二个要转化成的数据类型
    41. list3.stream()
    42. /* .map(new Function() {
    43. @Override
    44. public Integer apply(String s) {
    45. String[] str = s.split("-");
    46. String ageString = str[1];
    47. int age = Integer.parseInt(ageString);
    48. return age;
    49. }
    50. })*/
    51. .map(s->Integer.parseInt(s.split("-")[1]))
    52. .forEach(s-> System.out.println(s));
    53. }
    54. }

    3.Stream流终结方法

              名称                                                    说明
    void forEach(Consumer action)                遍历
    long count()                                                 统计
    toArray()                                       收集流中的数据,放到数组中
    collect(Collector collector)         收集流中的数据,放到集合中

    前三个方法的代码示范: 

    1. import java.util.ArrayList;
    2. import java.util.Arrays;
    3. import java.util.Collections;
    4. import java.util.function.IntFunction;
    5. public class Test1 {
    6. public static void main(String[] args) {
    7. ArrayList list = new ArrayList<>();
    8. Collections.addAll(list,"asd","zxc","qwe");
    9. //1.forEach(Consumer action)
    10. list.stream().forEach(s -> System.out.println(s));
    11. //2.count()
    12. long count1 = list.stream().count();
    13. System.out.println(count1);
    14. //3.toArray()
    15. //转化成什么类型的数组
    16. String[] str = list.stream().toArray(new IntFunction() {
    17. @Override
    18. public String[] apply(int value) {
    19. return new String[value];
    20. }
    21. });
    22. System.out.println(Arrays.toString(str));
    23. //简化写法
    24. String[] str1 = list.stream().toArray(value -> new String[value]);
    25. System.out.println(Arrays.toString(str));
    26. }
    27. }

    结果展示: 

    三.方法引用

    1.引用方法必须是函数式接口

    2.被引用的方法必须已经存在

    3.被引用方法的形参返回值需要和抽象方法保持一致

    4.被引用的方法的功能要满足当前需求

    5. :: 是方法引用符

    代码示范:

    1. import java.util.ArrayList;
    2. import java.util.Arrays;
    3. import java.util.Comparator;
    4. public class Test1 {
    5. public static void main(String[] args) {
    6. Integer[] arr = {1,4,7,2,6,3,5};
    7. //将数组从大到小排序
    8. //1.匿名内部类
    9. /* Arrays.sort(arr, new Comparator() {
    10. @Override
    11. public int compare(Integer o1, Integer o2) {
    12. return o2-o1;
    13. }
    14. });*/
    15. //2.lambda表达式
    16. /*Arrays.sort(arr,(o1, o2)-> o2-o1);*/
    17. //3.方法引用
    18. //::方法引用符
    19. Arrays.sort(arr,Test1::subtraction);
    20. System.out.println(Arrays.toString(arr));
    21. }
    22. public static int subtraction(int num1,int num2){
    23. return num2-num1;
    24. }
    25. }

    结果展示:

     1.引用静态方法

    格式: 类名::静态方法

    例如: Integer::parseInt

    代码示范: 

    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. import java.util.function.Function;
    4. public class Test2 {
    5. public static void main(String[] args) {
    6. ArrayList list = new ArrayList<>();
    7. Collections.addAll(list,"1","2","3","4","5");
    8. /*list.stream().map(new Function() {
    9. @Override
    10. public Integer apply(String s) {
    11. Integer i = Integer.parseInt(s);
    12. return i;
    13. }
    14. }).forEach(s-> System.out.println(s));*/
    15. list.stream()
    16. .map(Integer::parseInt)
    17. .forEach(s-> System.out.println(s));
    18. }
    19. }

    结果展示: 

    2.引用成员方法

    格式:  对象::成员方法

    (1)其他类: 其他类对象::方法名

    (2)本类: this::方法名  (引用处不能是静态方法)

    (3)父类: super::方法名 (引用处不能是静态方法)

    代码示范: 第一个是类的代码,第二个是测试代码

    1. public class Demo1 {
    2. public static boolean stringJudge(String s){
    3. return s.startsWith("小")&&s.length()==2;
    4. }
    5. }
    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. import java.util.function.Predicate;
    4. public class Test3 {
    5. public static void main(String[] args) {
    6. ArrayList list = new ArrayList<>();
    7. Collections.addAll(list,"小明","小红","小张","小李飞刀","张三","李四");
    8. //普通
    9. list.stream().filter(new Predicate() {
    10. @Override
    11. public boolean test(String s) {
    12. return s.startsWith("小")&&s.length()==2;
    13. }
    14. }).forEach(s-> System.out.println(s));
    15. System.out.println("=========================");
    16. //简化
    17. list.stream()
    18. .filter(s->s.startsWith("小")&&s.length()==2)
    19. .forEach(s-> System.out.println(s));
    20. System.out.println("=========================");
    21. //方法引用
    22. list.stream()
    23. .filter(Demo1::stringJudge)
    24. .forEach(s-> System.out.println(s));
    25. }
    26. }

    结果展示: 

    3.引用结构方法

    格式: 类名::new

    例如: Student::new

    代码示范: 第一个是Student类的代码,第二个是测试类的代码

    1. public class Student {
    2. private String name;
    3. private int age;
    4. public Student() {
    5. }
    6. //str是stream流中的数据
    7. public Student(String str) {
    8. String[] arr = str.split(",");
    9. this.name = arr[0];
    10. this.age = Integer.parseInt(arr[1]);
    11. }
    12. public Student(String name, int aeg) {
    13. this.name = name;
    14. this.age = aeg;
    15. }
    16. /**
    17. * 获取
    18. * @return name
    19. */
    20. public String getName() {
    21. return name;
    22. }
    23. /**
    24. * 设置
    25. * @param name
    26. */
    27. public void setName(String name) {
    28. this.name = name;
    29. }
    30. /**
    31. * 获取
    32. * @return aeg
    33. */
    34. public int getAge() {
    35. return age;
    36. }
    37. /**
    38. * 设置
    39. * @param age
    40. */
    41. public void setAge(int age) {
    42. this.age = age;
    43. }
    44. public String toString() {
    45. return "Student{name = " + name + ", aeg = " + age + "}";
    46. }
    47. }
    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. import java.util.List;
    4. import java.util.function.Function;
    5. import java.util.stream.Collectors;
    6. public class Test4 {
    7. public static void main(String[] args) {
    8. ArrayList list = new ArrayList<>();
    9. Collections.addAll(list,"小明,18","小红,19","小张,20","小李飞刀,21","张三,22","李四,23");
    10. //封装成Student对象并收集到List集合中
    11. //普通方法
    12. List newList = list.stream().map(new Function() {
    13. @Override
    14. public Student apply(String s) {
    15. String[] arr = s.split(",");
    16. String name = arr[0];
    17. int age = Integer.parseInt(arr[1]);
    18. return new Student(name, age);
    19. }
    20. }).collect(Collectors.toList());
    21. System.out.println(newList);
    22. System.out.println("==========================");
    23. //引用构造方法
    24. List newList2 = list.stream()
    25. .map(Student::new)
    26. .collect(Collectors.toList());
    27. System.out.println(newList2);
    28. }
    29. }

    结果展示: 

     4.使用类名引用成员方法

    格式: 类名::成员方法

    例如: String::substring

    注意: 被引用的方法形参是跟抽象方法第二个参数后面的保持一致

    代码示范: 

    1. import java.util.ArrayList;
    2. import java.util.Collections;
    3. import java.util.function.Function;
    4. public class Test5 {
    5. public static void main(String[] args) {
    6. ArrayList list = new ArrayList<>();
    7. Collections.addAll(list,"aaa","bbb","ccc");
    8. //把数据变成大写然后遍历
    9. //普通
    10. list.stream().map(new Function() {
    11. @Override
    12. public String apply(String s) {
    13. return s.toUpperCase();
    14. }
    15. }).forEach(s-> System.out.println(s));
    16. System.out.println("==========================");
    17. //引用方法
    18. list.stream()
    19. .map(String::toUpperCase)
    20. .forEach(s-> System.out.println(s));
    21. }
    22. }

    结果展示: 

    5.引用数组的构造方法

    格式: 数据类型[ ]::new

    例如: Integer::new

    注意: 数组的类型,需要跟流中数组的类型保持一致

    代码示范: 

    1. import java.util.ArrayList;
    2. import java.util.Arrays;
    3. import java.util.Collections;
    4. import java.util.function.IntFunction;
    5. public class Test6 {
    6. public static void main(String[] args) {
    7. ArrayList list = new ArrayList<>();
    8. Collections.addAll(list,1,2,3,4,5,6);
    9. //普通写法
    10. Integer[] arr1 = list.stream().toArray(new IntFunction() {
    11. @Override
    12. public Integer[] apply(int value) {
    13. return new Integer[value];
    14. }
    15. });
    16. //引用方法
    17. Integer[] arr2 = list.stream().toArray(Integer[]::new);
    18. System.out.println(Arrays.toString(arr1));
    19. System.out.println("===================");
    20. System.out.println(Arrays.toString(arr2));
    21. }
    22. }

    结果示范: 

  • 相关阅读:
    修改密码复杂度
    C/C++---------------LeetCode第1394.找出数组中的幸运数
    【MySql】深入了解 MySQL 中的 INNER JOIN 和 OUTER JOIN
    三位球形模型应用
    Blazor前后端框架Known-V1.2.16
    进公司第一天 git流程
    网络规划与设计>应用架构建模
    【Webpack】webpack5 模块联邦(Module Federation)
    【Java 进阶篇】Java Cookie共享:让数据穿越不同应用的时空隧道
    单板基础元器件之——电感
  • 原文地址:https://blog.csdn.net/guaiwu_/article/details/128137933