十五、集合进阶——不可变集合 、Stream流 和 方法引用

不可变集合 和 Stream流

  • 一、创建不可变集合
  • 二、Stream流
    • 2.1 初识Stream流
    • 2.2Stream流的中间方法
    • 2.3Stream流的终结方法
  • 三、练习
    • 练习1:数据过滤
    • 练习2:数据操作
    • 练习3:数据操作
  • 四、方法引用
    • 4.1 初识 方法引用
    • 4.2 引用 静态方法
    • 4.3 引用 成员方法
    • 4.4 引用 构造方法
    • 4.5 使用类名引用成员方法
    • 4.6 引用数组的构造方法
    • 总结
  • 五、综合练习


一、创建不可变集合

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
		/*创建不可变的List集合*/
        List<String> list = List.of("张三", "李四", "王五", "赵六", "钱七");

        System.out.println(list.get(0));
        System.out.println(list.get(1));
        System.out.println(list.get(2));
        System.out.println(list.get(3));
        System.out.println(list.get(4));

        System.out.println("=====================");
        for (String s : list) {
            System.out.println(s);
        }

        System.out.println("======================");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }

        System.out.println("====================");

        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        list.forEach(s -> System.out.println(s));
        
    }

使用remove、add等修改方法均会报错
在这里插入图片描述

二、Stream流

2.1 初识Stream流

在这里插入图片描述

public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张无忌");
        list1.add("周芷若");
        list1.add("赵敏");
        list1.add("张强");
        list1.add("张三丰");

        //0.把所有以“张”开头的元素存储到新集合中
        ArrayList<String> list2 = new ArrayList<>();
        for (String name : list1) {
            if (name.startsWith("张")){
                list2.add(name);
            }
        }
        System.out.println(list2);

        //1.把“张”开头的,长度为3的元素再存储到新集合中
        ArrayList<String> list3 = new ArrayList<>();
        for (String name : list2) {
            if (name.length()==3){
                list3.add(name);
            }
        }
        System.out.println(list3);

        //2.遍历打印最终结果
        for (String name : list3) {
            System.out.println(name);
        }

		//Stream流方法
		list1.stream().filter(name -> name.startsWith("张")).filter(name->name.length()==3).forEach(name -> System.out.println(name));
    }

在这里插入图片描述
在这里插入图片描述
Stream流的作用
结合了Lambda表达式,简化集合、数组的操作
在这里插入图片描述
Stream流的使用步骤

  1. 先得到一条Stream流(流水线),并把数据放上去
  2. 使用中间方法对流水线上的数据进行操作
  3. 使用终结方法对流水线上的数据进行操作

在这里插入图片描述

  1. 单列集合
public static void main(String[] args) {
        //0.单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"a","c","b","d","e");

        /*Stream<String> stream = list.stream();
        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/

        list.stream().forEach(s-> System.out.println(s));
    }
  1. 双列集合
public static void main(String[] args) {
        //1.双列集合
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("aaa", 111);
        hm.put("bbb", 222);
        hm.put("ccc", 333);
        hm.put("ddd", 444);

        //第一种获取Stream流的方法
        hm.entrySet().stream().forEach(s -> System.out.println(s));
        System.out.println("---------------------");

        //第二种获取stream流的方法
        hm.keySet().stream().forEach(s -> System.out.println(s + " = " + hm.get(s)));

    }
  1. 数组
public static void main(String[] args) {
        //数组
        //0.创建数组
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        //1.获取Stream流
        Arrays.stream(arr).forEach(num-> System.out.println(num));
    }
  1. 一堆零散数据
public static void main(String[] args) {
        //一堆零散数据
        Stream.of(1, 2, 3, 4, 5).forEach(num -> System.out.println(num));

        System.out.println("-----------------------");

        Stream.of("a", "b", "c", "d", "e").forEach(s -> System.out.println(s));
    }

注意
Stream接口中静态方法of的细节:

  • 方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
  • 但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中。

2.2Stream流的中间方法

在这里插入图片描述

  • 注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
  • 注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠上", "张良", "王二麻子", "谢广坤");

        //0.过滤
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张");
            }
        }).forEach(name -> System.out.println(name));

        System.out.println("================");

        list.stream().filter(name -> name.startsWith("张")).forEach(name -> System.out.println(name));

        System.out.println("=================   1.");

        //1.获取前几个元素
        list.stream().limit(3).forEach(name -> System.out.println(name));

        System.out.println("==================   2.");

        //2.跳过前几个元素
        list.stream().skip(3).forEach(name -> System.out.println(name));


        System.out.println("==========课堂练习=============");
        //课堂练习:"张强", "张三丰", "张翠上"
        list.stream()
                .skip(3)
                .limit(3)
                .forEach(name -> System.out.println(name));
    }

public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "张无忌", "张无忌", "张无忌", "张强", "张三丰", "张翠上", "张良", "王二麻子", "谢广坤");

        ArrayList<String> list2 = new ArrayList<>();

        Collections.addAll(list2, "周芷若", "赵敏");

        //0.元素去重
        list1.stream().distinct().forEach(name -> System.out.println(name));

        System.out.println("=======================");

        //1.合并a和b两个流为一个流
        Stream.concat(list1.stream(), list2.stream()).forEach(s -> System.out.println(s));

    }

public static void main(String[] args) {
        //类型转换
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-24", "周芷若-21", "赵敏-30", "张强-55", "张三丰-32", "张翠上-24", "张良-17", "王二麻子-26", "谢广坤-45");

        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                String ageString = arr[1];
                int age = Integer.parseInt(ageString);
                return age;
            }
        }).forEach(age -> System.out.println(age));

        System.out.println("--------------------");
        
        list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(age-> System.out.println(age));
    }

2.3Stream流的终结方法

在这里插入图片描述

public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠上", "张良", "王二麻子", "谢广坤");

        //0.遍历
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println("================");
        list.stream().forEach(s -> System.out.println(s));


        System.out.println("----------------------");
        //1.统计
        long count = list.stream().count();
        System.out.println(count);

        System.out.println("=======================");
        //2.收集流中的数据,放到数组中
        Object[] arr1 = list.stream().toArray();
        System.out.println(Arrays.toString(arr1));

        System.out.println("----------------------");

        /*toArray方法的参数的作用:负责创建一个指定类型的数组
        * toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
        * toArray方法的返回值:是一个装着流里面所有数据的数组*/
        String[] arr2 = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr2));

        System.out.println("-------------------");
        String[] arr3 = list.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(arr3));
    }
public static void main(String[] args) {
        //收集流中的数据,放到集合中
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-男-24", "周芷若-女-21", "赵敏-女-30", "张强-男-55", "张三丰-男-32", "张翠上-女-24", "张良-男-17", "王二麻子-女-26", "谢广坤-男-45");

        //0.收集到List集合当中
        //需求:把所有的男性收集起来
        List<String> newList = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toList());
        System.out.println(newList);

        //1.收集到Set集合当中
        //需求:把所有的男性收集起来
        Set<String> newSet = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(newSet);

        1.收集到Map集合当中
        /*注意点:
        如果我们要收集到Map集合当中,键不能重复,否则会报错*/

        //收集Map集合当中
        //谁作为键,谁作为值.
        //我要把所有的男性收集起来
        //键:姓名。 值:年龄
        Map<String, Integer> map = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                /*
                 *   toMap : 参数一表示键的生成规则
                 *           参数二表示值的生成规则
                 *
                 * 参数一:
                 *       Function泛型一:表示流中每一个数据的类型
                 *               泛型二:表示Map集合中键的数据类型
                 *
                 *        方法apply形参:依次表示流里面的每一个数据
                 *               方法体:生成键的代码
                 *               返回值:已经生成的键
                 *
                 *
                 * 参数二:
                 *        Function泛型一:表示流中每一个数据的类型
                 *                泛型二:表示Map集合中值的数据类型
                 *
                 *       方法apply形参:依次表示流里面的每一个数据
                 *               方法体:生成值的代码
                 *               返回值:已经生成的值
                 *
                 * */
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.split("-")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split("-")[2]);
                    }
                }));
        System.out.println(map);

        Map<String, Integer> map2 = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(
                        s -> s.split("-")[0],
                        s -> Integer.parseInt(s.split("-")[2])
                ));
        System.out.println(map2);
    }

在这里插入图片描述

三、练习

练习1:数据过滤

	定义一个集合,并添加一些整数  1,2,3,4,5,6,7,8,9,10
   		 过滤奇数,只留下偶数。
    	并将结果保存起来
 public static void main(String[] args) {
        /*定义一个集合,并添加一些整数  1,2,3,4,5,6,7,8,9,10
                过滤奇数,只留下偶数。
                并将结果保存起来*/

        //0.创建一个集合
        ArrayList<Integer> list = new ArrayList<>();

        //2。添加数据
        Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        //3.过滤奇数,只留下偶数。并将结果保存起来
        List<Integer> newlist = list.stream()
                .filter(num -> num % 2 == 0)
                .collect(Collectors.toList());

        System.out.println(newlist);
    }

练习2:数据操作

    创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
        "zhangsan,23"
        "lisi,24"
        "wangwu,25"
    保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
public static void main(String[] args) {
        /*
        *  创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
            "zhangsan,23"
            "lisi,24"
            "wangwu,25"
        保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值*/

        //0.创建一个ArrayList集合
        ArrayList<String> list = new ArrayList<>();

        //1.添加字符串
        Collections.addAll(list, "zhangsan,23", "lisi,24", "wangwu,25");

        //2.保留年龄大于等于24岁的人
        Map<String, Integer> map = list.stream()
                .filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                //将结果收集到Map集合中,姓名为键,年龄为值
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.split(",")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split(",")[1]);
                    }
                }));
        System.out.println(map);

        //Lambda表达式
        Map<String, Integer> map1 = list.stream()
                .filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                .collect(Collectors.toMap(
                        s -> s.split(",")[0],
                        n -> Integer.parseInt(n.split(",")[1])));
        System.out.println(map1);
    }

练习3:数据操作

现在有两个ArrayList集合,分别存储6名男演员的名字和年龄以及6名女演员的名字和年龄。
    姓名和年龄中间用逗号隔开。
    比如:张三,23
    要求完成如下的操作:
    1,男演员只要名字为3个字的前两人
    2,女演员只要姓杨的,并且不要第一个
    3,把过滤后的男演员姓名和女演员姓名合并到一起
    4,将上一步的演员信息封装成Actor对象。
    5,将所有的演员对象都保存到List集合中。
    备注:演员类Actor,属性有:name,age

    男演员:  "蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27"
    女演员:  "赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33"
public static void main(String[] args) {
        /*
        * 现在有两个ArrayList集合,分别存储6名男演员的名字和年龄以及6名女演员的名字和年龄。
        姓名和年龄中间用逗号隔开。
        比如:张三,23
        要求完成如下的操作:
        1,男演员只要名字为3个字的前两人
        2,女演员只要姓杨的,并且不要第一个
        3,把过滤后的男演员姓名和女演员姓名合并到一起
        4,将上一步的演员信息封装成Actor对象。
        5,将所有的演员对象都保存到List集合中。
        备注:演员类Actor,属性有:name,age

        男演员:  "蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27"
        女演员:  "赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33"*/

        //0.有两个ArrayList集合
        ArrayList<String> boyList = new ArrayList<>();
        ArrayList<String> girlList = new ArrayList<>();

        //1.存储6名男演员的名字和年龄以及6名女演员的名字和年龄
        Collections.addAll(boyList, "蔡坤坤,24", "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");
        Collections.addAll(girlList, "赵小颖,35", "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");

        //2.男演员只要名字为3个字的前两人
        Stream<String> boy = boyList.stream()
                .filter(s -> s.split(",")[0].length() == 3)
                .limit(2);

        //3.女演员只要姓杨的,并且不要第一个
        Stream<String> girl = girlList.stream()
                .filter(s -> s.split(",")[0].startsWith("杨"))
                .skip(1);

        //4.把过滤后的男演员姓名和女演员姓名合并到一起
        /*List<Actor> actors = Stream.concat(boy, girl)
                //将上一步的演员信息封装成Actor对象
                .map(new Function<String, Actor>() {
                    @Override
                    public Actor apply(String s) {
                        String name = s.split(",")[0];
                        int age = Integer.parseInt(s.split(",")[1]);
                        return new Actor(name, age);
                    }
                })
                //将所有的演员对象都保存到List集合中
                .collect(Collectors.toList());

        System.out.println(actors);*/

        System.out.println("====================");
        List<Actor> actors2 = Stream.concat(boy, girl)
                //将上一步的演员信息封装成Actor对象
                .map(s -> new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
                //将所有的演员对象都保存到List集合中
                .collect(Collectors.toList());
        System.out.println(actors2);
    }

四、方法引用

4.1 初识 方法引用

在这里插入图片描述
在这里插入图片描述
把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体
在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
        //需求:创建一个数组,进行倒序排序
        Integer[] arr = {3, 5, 4, 1, 6, 2};
        System.out.println(Arrays.toString(arr));
        //匿名内部类
        /*Arrays.sort(arr, new Comparator<>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        */

        //Lambda表达式
        /*Arrays.sort(arr, (Integer o1, Integer o2) -> {
            return o2 - o1;
        });*/

        //Lambda表达式简化格式
        /*Arrays.sort(arr, (o1, o2) -> o2 - o1);*/

        //方法引用
        /*表示引用FunctionDemo1类里面的subtraction方法
        * 把这个方法当做抽象方法的方法体*/
        Arrays.sort(arr,FunctionDemo1::subtraction);


        System.out.println(Arrays.toString(arr));
    }

    public static int subtraction(int num1, int num2) {
        return num2 - num1;
    }

在这里插入图片描述

在这里插入图片描述

4.2 引用 静态方法

在这里插入图片描述

public static void main(String[] args) {
        /*练习:
         * 集合中有以下数字,要求把他们都变成int类型
         * "1" "2" "3" "4" "5"*/

        //0.创建集合并添加元素
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "1", "2", "3", "4", "5");

        //把他们都变成int类型
        /*list.stream()
                .map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        })
                .forEach(s-> System.out.println(s));*/

        list.stream()
                .map(Integer::parseInt)
                .forEach(s -> System.out.println(s));
    }

4.3 引用 成员方法

在这里插入图片描述

  1. 其他类
public static void main(String[] args) {
        /*练习:
         * 集合中有一些名字,按照要求过滤数据*/

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");

        //过滤姓张的且长度为3的姓名
        /*list.stream()
                .filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));*/

        /*list.stream()
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(String s) {
                        return s.startsWith("张") && s.length() == 3;
                    }
                }).forEach(s -> System.out.println(s));*/


        list.stream().filter(new StringOpreation()::stringJudge)
                .forEach(s-> System.out.println(s));
package Function;

public class StringOpreation {
    public boolean stringJudge(String s){
        return s.startsWith("张") && s.length() == 3;
    }
}


  1. 本类
package Function;

import java.util.ArrayList;
import java.util.Collections;

public class FunctionDemo3 {
    public static void main(String[] args) {
        /*练习:
         * 集合中有一些名字,按照要求过滤数据*/

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");

        //过滤姓张的且长度为3的姓名
        /*list.stream()
                .filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));*/

        /*list.stream()
                .filter(new Predicate<String>() {
                    @Override
                    public boolean test(String s) {
                        return s.startsWith("张") && s.length() == 3;
                    }
                }).forEach(s -> System.out.println(s));*/

        //本类
        //静态方法中是没有this的
        /*list.stream()
                .filter(this::stringJudge)
                .forEach(s-> System.out.println(s));*/
        list.stream()
                .filter(FunctionDemo3::stringJudge)
                .forEach(s-> System.out.println(s));
    }

    public static boolean stringJudge(String s){
        return s.startsWith("张") && s.length() == 3;
    }
}

在这里插入图片描述

package Function.game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

public class LoginJFrame extends MyJFrame {
    JButton go = new JButton("Go!!!");

    public LoginJFrame() {
        //设置图标
        setIconImage(Toolkit.getDefaultToolkit().getImage("day26_code\\src\\Function\\game\\image\\logo.jpg"));

        //设置界面
        initJFrame();

        //添加组件
        initView();

        this.setVisible(true);

    }

    private void initView() {
        JLabel image = new JLabel(new ImageIcon("day26_code\\src\\Function\\game\\image\\kit.jpg"));
        image.setBounds(100, 50, 174, 174);
        this.getContentPane().add(image);

        go.setFont(new Font(null,1,20));
        go.setBounds(120,274,150,50);
        go.setBackground(Color.WHITE);
        //本类
//        go.addActionListener(this::method1);

        //父类
        go.addActionListener(super::method2);
        this.getContentPane().add(go);
    }

    private void initJFrame() {
        this.setTitle("随机点名器");
        this.setSize(400, 500);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.setLayout(null);
        this.getContentPane().setBackground(Color.WHITE);
        this.setAlwaysOnTop(true);
    }

    //本类中的方法
    public void method1(ActionEvent e) {
        System.out.println("Go按钮被点击了");
    }
}

package Function.game;

import javax.swing.*;
import java.awt.event.ActionEvent;

public class MyJFrame extends JFrame {
    public void method2(ActionEvent e){
        System.out.println("父类:Go按钮被点击了");
    }
}

4.4 引用 构造方法

在这里插入图片描述

public static void main(String[] args) {
        /*练习
         * 集合里面存储姓名和年龄,比如:张无忌,15
         * 要求:将数据封装成Student对象并收集到List集合中*/
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张翠山,40", "张良,35", "王二麻子,37");

        /*List<Student> newList = list.stream()
                .map(new Function<String, Student>() {
                    @Override
                    public Student apply(String s) {
                        String[] arr = s.split(",");
                        String name = arr[0];
                        int age = Integer.parseInt(arr[1]);
                        return new Student(name, age);
                    }
                })
                .collect(Collectors.toList());

        */

        List<Student> newList = list.stream()
                .map(Student::new)
                .collect(Collectors.toList());
        
        System.out.println(newList);
    }
package Function;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String str) {
        String[] arr = str.split(",");
        this.name = arr[0];
        this.age = Integer.parseInt(arr[1]);
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     *
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     *
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}


4.5 使用类名引用成员方法

在这里插入图片描述
该方法的规则:

  1. 需要有函数式接口
  2. 被引用的方法必须存在
  3. 被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
  4. 被引用方法 的功能 需要满足当前的需求

抽象方法形参的详解

  • 第一个参数:
    • 表示被引用方法的调用者,决定了可以引用哪些类中的方法
    • 在Stream流当中,第一个参数一般都表示流里面的每一个数据
    • 假设流里面的数据是字符串,那么使用这种方式进行方法引用,只能引用String这个类中的方法
  • 第二个参数到最后一个参数:
    • 跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要时无参的成员方法

局限性:

  • 不能引用所有类中的成员方法
  • 是跟抽象方法的第一个参数有关,这个参数是什么类型的,那么就只能引用这个类中的方法
public static void main(String[] args) {
        /*练习
         * 集合里面有一些字符串,要求变成大写后进行输出*/

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "aaa", "bbb", "ddd");

        /*list.stream()
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.toUpperCase();
                    }
                })
                .forEach(s -> System.out.println(s));*/

        list.stream()
                .map(String::toUpperCase)
                .forEach(s -> System.out.println(s));
    }

4.6 引用数组的构造方法

在这里插入图片描述

public static void main(String[] args) {
        /*练习:
        * 集合中存储一些整数,收集到数组当中*/

        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9);

        /*Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                return new Integer[value];
            }
        });*/
        Integer[] arr = list.stream().toArray(Integer[]::new);

        System.out.println(Arrays.toString(arr));
    }

总结

在这里插入图片描述
在这里插入图片描述

五、综合练习

在这里插入图片描述

public static void main(String[] args) {
        /*
           练习1:
                集合中存储一些字符串的数据,比如:张三,23
                收集到Student类型的数组当中(使用方法引用完成)

           练习2:
                创建集合添加学生对象,学生对象属性:name, age
                只获取姓名并放到 数组当中(使用方法引用完成)

           练习3:
                创建集合添加学生,学生对象属性:name, age
                把姓名和年龄拼接成:张三-23 的字符串,并放到数组当中(使用方法引用完成)*/

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20", "张翠山,40", "张良,35", "王二麻子,37");


        /*练习1:
                集合中存储一些字符串的数据,比如:张三,23
                收集到Student类型的数组当中(使用方法引用完成)*/
        Student[] arr1 = list.stream()
                .map(Student::new)
                .toArray(Student[]::new);
        System.out.println(Arrays.toString(arr1));

        System.out.println("========================");

        /*练习2:
                创建集合添加学生对象,学生对象属性:name, age
                只获取姓名并放到 数组当中(使用方法引用完成)*/
        ArrayList<Student> list1 = new ArrayList<>();
        list1.add(new Student("张三", 23));
        list1.add(new Student("lisi", 24));
        list1.add(new Student("wangwu", 25));

        /*String[] arr2 = list1.stream()
                .map(new Function<Student, String>() {
                    @Override
                    public String apply(Student student) {
                        return student.getName();
                    }
                })
                .toArray(String[]::new);*/
        String[] arr2 = list1.stream()
                .map(Student::getName)
                .toArray(String[]::new);
        System.out.println(Arrays.toString(arr2));

        System.out.println("=============================");
        /*练习3:
                创建集合添加学生,学生对象属性:name, age
                把姓名和年龄拼接成:张三-23 的字符串,并放到数组当中(使用方法引用完成)*/
        ArrayList<Student> list3 = new ArrayList<>();
        list3.add(new Student("张三", 23));
        list3.add(new Student("lisi", 24));
        list3.add(new Student("wangwu", 25));

        /*String[] arr3 = list3.stream()
                .map(new Function<Student, String>() {
                    @Override
                    public String apply(Student student) {
                        StringJoiner sj = new StringJoiner("-");
                        sj.add(student.getName());
                        sj.add(student.getAge() + "");
                        return sj.toString();
                    }
                })
                .toArray(String[]::new);*/

        String[] arr3 = list3.stream()
                .map(Test1::concatStr)
                .toArray(String[]::new);

        System.out.println(Arrays.toString(arr3));

    }

    public static String concatStr(Student student){
        StringJoiner sj = new StringJoiner("-");
        sj.add(student.getName());
        sj.add(student.getAge() + "");
        return sj.toString();
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/418048.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

七通道NPN 达林顿管GC2003,专为符合标准 TTL 而制造,最高工作电压 50V,耐压 80V

GC2003 内部集成了 7 个 NPN 达林顿晶体管&#xff0c;连接的阵列&#xff0c;非常适合逻辑接口电平数字电路&#xff08;例 如 TTL&#xff0c;CMOS 或PMOS 上/NMOS&#xff09;和较高的电流/电压&#xff0c;如电灯电磁阀&#xff0c;继电器&#xff0c;打印机或其他类似的负…

形态学笔记:侵蚀+膨胀+开运算+闭运算+形态学梯度+顶帽运算+黑帽运算

形态学 一般在二值图上操作 输入&#xff1a;原图、操作结构内核 简单阈值 对于每个像素&#xff0c;应用相同的阈值。如果像素值小于阈值&#xff0c;则将其设置为0&#xff0c;否则将其设置为最大值 原图–>灰度图–>二值图 logo cv2.imread(./fans.jpg) # 参数1 …

初学HTMLCSS——盒子模型

盒子模型 盒子&#xff1a;页面中所有的元素&#xff08;标签&#xff09;&#xff0c;都可以看做是一个 盒子&#xff0c;由盒子将页面中的元素包含在一个矩形区域内&#xff0c;通过盒子的视角更方便的进行页面布局盒子模型组成&#xff1a;内容区域&#xff08;content&…

双指针问题(Java编写)

日升时奋斗&#xff0c;日落时自省 目录 一、移动零 二、盛水最多的容器 三、快乐数 四、复写零 五、三数之和 六、有效三角形的个数 七、四数之和 一、移动零 题目来源&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目主要内容就是将数组中所有的零移动到…

FPGA高端项目:FPGA基于GS2971的SDI视频接收+图像缩放,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI纯verilog图像缩放视频拼接应用本方案的SDI HLS图像缩放视频拼接应用本方案的SDI视频编码动态字符叠加输出应用本方案的SDI视频编码多路视频融合视频叠加应用FPGA的SDI…

Redis 群集部署

部署配置实验 实验环境 虚拟机 6台 centos7.9 网卡NAT模式 数量 1 组件包Redis安装包 设备 IP 备注 Centos01 192.168.9.31 Node1 Centos02 192.168.9.32 Node2 Centos03 192.168.9.33 Node3 Centos04 192.168.9.34 Node4 Centos05 192.168.9.35 Node5 C…

windows下安装npm

windows下安装了多个node.js如何切换npm。 下载nvm 下载nvm地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 安装nvm 这个是nodejs的安装位置&#xff0c;如果没有nodejs文件夹就新建一个(后来发现他会自动生成一个快捷方式) 设置setting.txt 打开安装…

新一轮寒潮来袭!浙江电网首次应用运载无人机进行输电线路除冰作业

近期&#xff0c;受低温雨雪冰冻天气的影响&#xff0c;浙江多地迎来罕见冻雨、冰雹天气&#xff0c;高海拔山区气温持续维持零摄氏度以下&#xff0c;部分输配电线路出现覆冰现象&#xff0c;部分地区电力供应受到影响。 为保障线路安全稳定运行&#xff0c;国网浙江供电公司于…

2019年上半年教师资格证考试《教育知识与能力》(中学)题

2.苏联教育家赞可夫倡导的是&#xff08;C &#xff09;。 A发现学习理论 B教学过程最优化理论 C教学与发展理论 D范例教学理论 9.我国《基础教育课程改革纲要&#xff08;试行&#xff09;》规定&#xff0c;在课程设置上&#xff0c;高中阶段&#xff08;B &#xff09;。…

Java学习笔记------接口

接口 接口就是一种规则,对行为的抽象 定义和使用接口 用关键字interface来定义&#xff0c;public interface 接口名{} 接口不能实例化 接口和类之间是实现关系&#xff0c;通过impls关键字表示 public class 类名 implements 接口名{} 接口的子类&#xff08;实现类&am…

数据可视化基础与应用-02-基于powerbi实现医院数据集的指标体系的仪表盘制作

总结 本系列是数据可视化基础与应用的第02篇&#xff0c;主要介绍基于powerbi实现医院数据集的指标体系的仪表盘制作。 数据集描述 医生数据集doctor 医生编号是唯一的&#xff0c;名称会存在重复 医疗项目数据projects 病例编号是唯一的&#xff0c;注意这个日期编号不是真…

HarmonyOS—开发云数据库

您可以在云侧工程下开发云数据库资源&#xff0c;包括创建对象类型、在对象类型中添加数据条目、部署云数据库。 创建对象类型 对象类型&#xff08;即ObjectType&#xff09;用于定义存储对象的集合&#xff0c;不同的对象类型对应的不同数据结构。每创建一个对象类型&#…

PackagingTool_x64_v2.0.1.0图片转档打包二进制文件合并字库生成图片软件介绍

继去年12月份发布的打包软件PackagingTool v1.4.0.2之后&#xff0c;今年再度投入精力&#xff0c;完善了软件功能&#xff0c;同时开发了几个更加实用的工具&#xff0c;可助力UI界面的设计开发。当前最新版本为PackagingTool_x64_v2.0.1.0&#xff0c;该版本主界面如下&#…

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…

5 分钟配置好 Electron 应用的图标

最近在开发博客本地客户端 HexoPress&#xff0c;应用做好后&#xff0c;需要打包&#xff0c;如果不希望打包出来 App 的图标用的是 Electron 默认的星球环绕的图标&#xff0c;那么需要自己制作图标。 制作图标 首先&#xff0c;你需要给各种操作系统制作一个满足要求的图标…

hcip--VLAN实验

一&#xff1a;实验要求 二&#xff1a; 实验分析 1.pc1和pc3在同一个vlan&#xff08;vlan2&#xff09;&#xff0c;因为是access接口模式&#xff0c;那么需和pc2/4/5/6不在同一个网 段&#xff0c;则是做路由器的子接口。 2. pc2/4/5/6在同一个网段&#xff0c;且需要实…

Java+SpringBoot,打造社区疫情信息新生态

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

FPGA-DDS原理及实现

DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有相对带宽大,频率转换时间短、分辨率高和相位连续性好等优点。较容易实现频率、相位以及幅度的数控调制,广泛应用于通信领域。 相位累加器是由N位加法器与N位寄存器构成,每个时钟周期的上升沿,加法器…

公司电脑ip所在地查询方法参考

公司局域网 可以看到这种方法查不出来 直接百度 直接被智能云识别了出来 询问gpt的方法 获得ipv6 curl ifconfig.me 但是ipv6好像对我们并没有多大帮助

自动化构建平台(三)Linux搭建私有的docker镜像库之Harbor的安装和使用详解

文章目录 前言一、Harbor的安装第一步&#xff1a;安装docker第二步&#xff1a;安装docker-compose第三步&#xff1a;安装Harbor 二、Harbor登录三、Harbor项目管理第一步&#xff1a;创建项目第二步&#xff1a;推送镜像 四、Harbor权限控制五、Harbor自动清理多余的镜像手动…