JAVASE进阶:高级写法——方法引用(Mybatis-Plus必学前置知识)

‍作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
上期文章:JAVASE进阶:一文精通Stream流+函数式编程
订阅专栏:JAVASE进阶
希望文章对你们有所帮助

相信大家都会用mybatis-plus,但可能只会用其中的一些简单增删改查,想要将mybatis-plus学深入,需要学会方法引用,这是一个很重要的内容。

高级写法——方法引用(Mybatis-Plus必学前置知识)

  • 概述
  • 引用静态方法
  • 引用成员方法
    • 引用其他类的成员方法
    • 引用本类和父类的成员方法
  • 引用构造方法
  • 其他调用方式
    • 使用类名引用成员方法
    • 引用数组的构造方法

概述

方法引用:把已经存在的方法拿过来用,当作函数式接口中抽象方法的方法体

对于数组排序,可以使用匿名内部类,也可以利用lambda表达式来简化,同时还可以使用方法引用Arrays.sort(arr, 比较规则),需要满足以下要求:

1、引用出处必须是函数式接口
2、被引用的方法必须存在
3、被引用方法的形参和返回值需要跟抽象方法一致
4、被引用的方法的功能要满足当前需求,这个方法应该要与匿名内部类一致(形参类型、返回值)

这里直接贴一个例子:

public class ArrayTest {
    public static void main(String[] args) {
        Integer[] arr = {3, 5, 4, 1, 6, 2};
        Arrays.sort(arr, ArrayTest::subtraction);
        System.out.println(Arrays.toString(arr));
    }
    public static int subtraction(int num1, int num2){
        return num2 - num1;
    }
}

其中,::表示方法引用符

引用静态方法

格式为类名::静态方法,例如Integer::parseInt
做一个小demo,把List中的"1",“2”,“3”,“4”,"5"转化为int类型:

public class ArrayTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "1","2","3","4","5");
        List<Integer> list1 = list.stream().map(Integer::parseInt).collect(Collectors.toList());
        System.out.println(list1);
    }
}

可以看到,Integer::parseInt在这里比lambda表达式的s->Integer.parseInt(s)还要便捷,但需要保证Integer类中的parseInt确实是传入String转化为int类型的,即可直接使用。

引用成员方法

引用成员方法的基本格式为对象::成员方法,这个对象的来源不同,方法的格式具体写法也会有一些区别:
1、其他类:其他类对象::方法名
2、本类:this::方法名
3、父类:super::方法名

引用其他类的成员方法

将集合中的的名字进行过滤,留下以"张"开头的,并且名字是3个字的。

可以先写匿名内部类:

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

观察这个匿名内部类重写方法中的形参为String类型,返回值为boolean类型的,但是java并没专门提供这样的方法,所以不能直接使用,因此我们可以新建一个类:

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

现在就可以引用这个成员方法了,但是需要注意,这里的方法不是静态方法,所以需要用对象调用成员方法,不是直接用类来调用的,需要创建这个对象出来:

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

引用本类和父类的成员方法

因为是在本类的,所以利用this关键字也是可以的,但是必须保证引用出不能是静态方法!因为在静态方法中,是不可能有this和super的。
引用本类:this::方法名
引用父类:super::方法名

引用构造方法

引用构造方法就是为了创建这个类的对象,其格式为类型::new,比如Student::new,做一个练习:在集合中存储姓名和年龄,将数据封装为Student对象并收集到List集合中。

先试用匿名内部类编写代码:

public class demo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌,15", "吗喽,13", "张三丰,100", "张良,35");
        List<Student> newList = list.stream().map(new Function<String, Student>() {
            @Override
            public Student apply(String s) {
                return new Student(s.split(",")[0], Integer.parseInt(s.split(",")[1]));
            }
        }).collect(Collectors.toList());
        System.out.println(newList);
    }
}

而如果要使用方法引用,必须要满足那4点要求,然而在这里却不满足被引用方法的形参和返回值,需要跟抽象方法的形参返回值保持一致的要求,这里的形参是String,返回值为Student类型,所以Student中需要专门有一个形参为String类型的构造方法,这种构造方式和一般的方式还是有点不一样的:
JAVASE进阶:高级写法——方法引用(Mybatis-Plus必学前置知识)_第1张图片
这样子,使用引用方法就不会再报错:

List<Student> newList = list.stream().map(Student::new).collect(Collectors.toList());

其他调用方式

使用类名引用成员方法

格式为类名::成员方法,例如String::substring,如下例中对集合中的一些字符串变成大写并输出:

	public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "aaa", "bbb", "ccc");
        List<String> newList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
        System.out.println(newList);
    }

引用数组的构造方法

格式为数据类型[]::new,例如int[]::new,做一个练习:集合中存储一些整数,收集到数组中去。
在这里肯定是只能使用toArray方法了,这种方法感觉用的还是有点少的,但是也肯定要掌握以下。
首先编写一下匿名内部类,这一块要是基础不是特别扎实的话也还是要捣鼓一会的:

	public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);
        Integer[] arr = list.stream().toArray(new IntFunction<Integer[]>() {
            @Override
            public Integer[] apply(int value) {
                //System.out.println(value);
                return new Integer[value];
            }
        });
        System.out.println(Arrays.toString(arr));
    }

主要就是要注意,IntFunction中的泛型装的是要处理的数据类型,这里放了一堆的整数可以当作是Integer[],注意不能写int不然会报错。
apply中的value不是指元素值,而是这个数组的长度,因此需要返回Integer[value]。

因此转换为方法引用的代码如下所示,由于上面的形参必须是Integer[]类型的,所以这边也不能用int[]

	public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5);
        Integer[] arr = list.stream().toArray(Integer[]::new);
        System.out.println(Arrays.toString(arr));
    }

你可能感兴趣的:(JAVASE进阶,java,mybatis-plus,方法引用,面试,lambda)