2.4.引用构造方法

一.引用构造方法的格式:

  • 引用构造方法的目的:创建类的对象

  • 方法引用有4个前提条件:1.引用处需要有函数式接口;2.被引用的方法必须已经存在;3.被引用的方法的形参和返回值,需要跟抽象方法的形参和返回值保持一致;4.被引用的方法的功能需要满足当前的需求

  • 在方法引用的4个前提条件中第三条需要特别注意:构造方法没有返回值,意味着构造方法无法返回和抽象方法一样的返回值,但是在构造方法运行完之后,对应的类对象就已经存在了->所以在引用构造方法时,构造方法的返回值不需要考虑,只需要保证构造方法运行完之后,生成的对象和抽象方法的返回值保持一致即可,其他的前提条件依旧


二.练习:

需求:

解答:

未使用方法引用前:

Student类:

package com.itheima.a01myfunction;
​
public class Student {
    private String name;
    private int age;
​
​
    public Student() {
    }
​
    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 + "}";
    }
}

测试类:

package com.itheima.a01myfunction;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
​
public class FunctionDemo4 {
    public static void main(String[] args) {
        //1.创建集合对象
        ArrayList<String> list=new ArrayList<>();
​
        //2.添加数据
        Collections.addAll(list,"张无忌,15", "周芷若,14", "赵敏,13", "张强,20",
                "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
​
        //3.将数据封装成Student对象并收集到List集合中
        /* 数据原本是String型,现在要求封装成Student型
           ->意味着类型转换
           ->所以可以使用stream流里的map方法*/
        List<Student> newList = list.stream().map(new Function<String, Student>() { //第一个泛型:流里的数据的类型;第二个泛型:最终数据的类型
            @Override
            public Student apply(String s) { //s代表流里的每一个数据即集合list中的每一个元素
                //3.1.切割s:用,切割s,最终得出的数组中0索引是姓名,1索引是年龄->注:此时姓名和年龄都是String型即字符串型
                String[] arr = s.split(",");
                //3.2.提取姓名->注:姓名必须是字符串型,此时切割出的姓名是字符串型,所以不需要类型转换
                String name = arr[0];
                //3.3.提取年龄->注:年龄必须是整型,但此时切割出的年龄是字符串型,所以需要类型转换
                int age = Integer.parseInt(arr[1]);
                //3.4.将数据封装成Student对象
                Student student = new Student(name, age);
                //3.5.返回
                return student;
            }
        }).collect(Collectors.toList());  //3.6.收集到List集合中
​
        //4.打印newList集合
        System.out.println(newList);
    }
}
使用方法引用改写:

map方法中的形参Function是一个函数式接口,所以在map方法的形参的位置上可以用方法引用进行改写。

map方法中通过apply方法实现了将数据封装成Student对象->map方法就是用于把流里的字符串对象转换为Student对象:

此时想要在map方法的形参的位置上通过方法引用进行改写,

就需要引用一个已经存在的方法且该方法可以帮我们完成apply方法的功能,其中,apply方法的主要功能就是将数据封装成Student对象,

所以可以在map方法的形参中引用一个可以实现apply方法的功能且可以将数据封装成Student对象的构造方法:(之所以引用构造方法,是因为构造方法就是用于封装对象的)

此时系统报错,但没有完全报错,只有new的位置报错了这里要想到方法引用的4条规则:

->1.引用处必须是函数式接口,此时map方法的形参Function就是函数式接口,符合

->2.被引用的方法必须已经存在,此时要引用的是Student类里的构造方法,在Student类里已经存在构造方法,符合;

->3和4.被引用的方法的形参和返回值,需要跟抽象方法的形参和返回值保持一致,而且被引用的方法的功能需要满足当前的需求,这里要注意的是:此时引用的是构造方法,引用构造方法时就不需要考虑方法的返回值了,此时的抽象方法指的是apply方法,apply方法的形参类型是String型,作用是实现将数据封装成Student对象,但在Student类里并没有形参类型是String型、作用是实现将数据封装成Student对象的构造方法,不符合,

所以只在new的位置会报错:(当引用的构造方法Student不存在时Student的位置才会报错,此时new也会跟着报错,因为构造方法Student不存在,意味着当前需求也完成不了)

所以只需要加一个形参类型是String型、作用是实现将数据封装成Student对象的构造方法即可,

该构造方法用于实现map方法中的方法引用,所以该构造方法的形参依次表示流里面的每一个数据,因此该构造方法的形参最好不要命名为name和age,防止和Student类里的成员变量name和age混淆:

Student类:

package com.itheima.a01myfunction;
​
public class Student {
    private String name;
    private int age;
​
​
    public Student() {
    }
​
    //这个构造方法用于实现map方法中的方法引用,此时形参依次表示流里面的每一个数据,因此最好不要命名为name,防止和Student类里的成员变量name混淆
    //该构造方法的作用是将形参数据封装成Student对象
    public Student(String str){ //str不是姓名,而是依次表示流里面的每一个数据
        //1.切割str:用,切割str,最终得出的数组中0索引是姓名,1索引是年龄->注:此时姓名和年龄都是String型即字符串型
        String[] arr = str.split(",");
        //2.提取姓名->注:姓名必须是字符串型,此时切割出的姓名是字符串型,所以不需要类型转换
        String name = arr[0];
        //3.把提取的姓名赋值给对应的Student类的姓名name
        this.name=name;
        //4.提取年龄->注:年龄必须是整型,但此时切割出的年龄是字符串型,所以需要类型转换
        int age = Integer.parseInt(arr[1]);
        //5.把提取的年龄赋值给对应的Student类的年龄age
        this.age=age;
        /*注:构造方法没有返回值,意味着该构造方法无法返回Student型,
             但是构造方法运行完之后,那么对应的类对象即Student对象就已经存在了,
             所以在引用构造方法时,返回值不需要考虑,只需要保证构造方法运行完之后,生成的对象和抽象方法的返回值保持一致即可,
             其他的前提条件依旧*/
    }
​
    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 + "}";
    }
}
​

测试类:

package com.itheima.a01myfunction;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
​
public class FunctionDemo4 {
    public static void main(String[] args) {
        //1.创建集合对象
        ArrayList<String> list = new ArrayList<>();
​
        //2.添加数据
        Collections.addAll(list, "张无忌,15", "周芷若,14", "赵敏,13", "张强,20",
                "张三丰,100", "张翠山,40", "张良,35", "王二麻子,37", "谢广坤,41");
​
        //3.将数据封装成Student对象并收集到List集合中
        /* 数据原本是String型,现在要求封装成Student型
           ->意味着类型转换
           ->所以可以使用stream流里的map方法*/
        List<Student> newList = list.stream().map(Student::new).collect(Collectors.toList());
​
        //4.打印newList集合
        System.out.println(newList);
​
​
    }
}
​

三.对于Stream流里的工具类Collectors,其中的toList方法:

上述图片的toList方法中,第243行代码里使用到了方法引用,new了一个ArrayList集合(使用了引用构造方法),然后用add方法把数据添加到List集合中(使用了引用成员方法)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值