方法引用

方法引用

概述

把已经有的方法拿过来用,当做函数式接口中抽象方法的方法体

方法引用符::

  • 引用处必须是函数式接口
  • 被引用的方法方法必须是已存在的
  • 被引用的方法的形参和返回值需要跟抽象方法保持一致
  • 被引用方法的功能要满足当前需求
package fangfayinyong;

import java.util.Arrays;

public class demo {
    public static void main(String[] args) {
        Integer[] arr = {1,2,3,4,5,6};
//        Arrays.sort(arr, new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return o2 - o1;
//            }
//        });

        //因为第二个参数的类型Comparator是一个函数式接口
        //lambda表达式
//        Arrays.sort(arr,(Integer o1, Integer o2)->{
//            return o2 - o1;
//        });

        //简化
//        Arrays.sort(arr,(o1,o2)-> o2-o1);

        //方法引用
        //条件满足

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



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

    //被引用的方法
    //可以是java已经写好的,也可以是一些第三方的工具类
    public static int subtraction(int num1,int num2){
        return num2 - num1;
    }
}
引用静态方法
  • 类名::静态方法
package fangfayinyong;

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

public class demo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"1","2","3","4","5");

        ArrayList<Integer> list2 = new ArrayList<>();
//        for(String s : list){
//            int i = Integer.parseInt(s);
//            list2.add(i)
//        }

//        list.stream().map(new Function<String, Integer>() {
//            public Integer apply(String s){
//                int i = Integer.parseInt(s);
//                return i;
//            }
//        }).forEach(s -> System.out.println(s));

        //方法引用
        list.stream().map(Integer::parseInt).forEach(s -> System.out.println(s));


    }
}
引用成员方法---其他类
  • 对象::方法名
package fangfayinyong;

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

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

public class demo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张辽","张文远","刘备","薛力铭","曹操","孙权");
        //过滤数据

        //lambda表达式
//        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 StringOperation()::stringJudge).forEach(s-> System.out.println(s));

    }
}
引用成员方法---本类
  • this::方法名
  • 引用处不能是静态方法
public class demo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张辽","张文远","刘备","薛力铭","曹操","孙权");
        //静态方法中没有this
//        list.stream().filter(this::stringJudge).forEach(s-> System.out.println(s));
        list.stream().filter(new demo3()::stringJudge).forEach(s-> System.out.println(s));

    }
    public boolean stringJudge(String s){
        return s.startsWith("张") && s.length() == 3;
    }
}
引用成员方法---父类
  • super::方法名
  • 引用处不能是静态方法
引用构造方法
  • 类名::new
  • 为了创建对象
public Student(String str) {
    String[] arr = str.split(",");
    this.name = arr[0];
    this.age = Integer.parseInt(arr[1]);
}
package fangfayinyong;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class demo4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张辽,22", "张文远,22", "刘备,33", "薛力铭,18", "曹操,33", "孙权,20");
        //封装成Student对象并收集到List集合中
//        List<Student> newList = list.stream().map(new Function<String, Student>() {
//            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());
//        System.out.println(newList);

        //方法引用改写
        List<Student> newList2 = list.stream().map(Student::new).collect(Collectors.toList());
        System.out.println(newList2);
    }
}
类名引用成员方法
  • 类名::成员方法
  • String::subString
  • 新增规则
    • 被引用方法的形参,需要跟抽象方法的第二个形参到最后一个形参保持一致,返回值需要保持一致
  • 抽象方法形参详解
    • 第一个参数表示被引用方法的调用者,表示了可以引用哪些类中的方法
    • 在stream流中,第一个参数一般表示流里面的每一个数据
    • 假设流里面的数据是字符串,使用这种方式进行方法引用,只能引用String这个类中的方法
    • 第二个参数到最后一个参数:跟被引用方法的形参保持一致,如果没有第二个参数,说明被引用的方法需要是无参的成员方法
  • 局限性:不能引用所有类中的成员方法
    • 是跟抽象方法的第一个参数有关,这个参数是什么类型,就只能引用这个类中的方法
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc","ddd","eee","FFF");
        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));
引用数组的构造方法
  • 数据类型[]::new
  • int[]::new
  • 为了创建一个数组
  • 数组的类型需要跟流中的数据类型保持一致
        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));//[1, 2, 3, 4, 5]

案例:

Student[] arr = list.stream().map(Student::new).toArray(Student[]::new);
Student[] arr = list.stream().map(Student::getName).toArray(Student[]::new);
posted @ 2023-08-29 23:50  lmcool-  阅读(22)  评论(0)    收藏  举报