← 返回首页
JavaSE基础教程(一百零七)
发表时间:2022-08-30 18:17:12
Java8新特征之-方法引用

双冒号运算操作符是类方法的句柄,是lambda表达式的一种简写。

1.双冒号(::)运算符

在Java 8中,双冒号(::)运算符称为方法引用。方法引用不执行任何操作,只是对现有方法的另一种调用。使用方法引用,可以获得更好的可读性。

大家平时最早接触双冒号方法引用的地方,就是把集合转换为stream流后的lambda表达式的遍历方式,如下:

 List<String> list = Arrays.asList("北京","上海","广州","深圳");
 list.forEach(System.out::println);

这里要特别强调一下,双冒号(::)运算符使用有两个大的前提条件,否则不适合使用方法引用。

双冒号(::)运算符有以下四种方法引用:

下来分别探讨这四种方法引用使用方式:

2.静态方法

将String列表转换为Integers列表,该方法引用静态方法Integer::parseInt。

List<String> list = Arrays.asList("1", "2", "3");
// method reference
List<Integer> list1 = list.stream()
                .map(Integer::parseInt).collect(Collectors.toList());
list1.forEach(System.out::println);

3.引用特定对象的实例方法

Students按成绩降序排序列表。我们可以参考compareBySalary特定对象的实例方法ComparatorProvider。

class ComparatorProvider {
    public int compareByAge(Students s1, Students s2) {
        return s1.getAge().compareTo(s2.getAge());
    }

    public int compareByName(Students s1, Students s2) {
        return s1.getName().compareTo(s2.getName());
    }

    public int compareByScore(Students s1, Students s2) {
        return s2.getScore().compareTo(s1.getScore());
    }
}

class Students {
    String name;
    Integer age;
    Integer score;

    public Students() {
    }

    public Students(String name, Integer age, Integer score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

public class Java8MethodReference2 {

    public static void main(String[] args) {

        List<Students> list = Arrays.asList(
                new Students("张三", 18, 98),
                new Students("李四", 19, 89),
                new Students("王五", 25, 78),
                new Students("赵六", 21, 90));

        ComparatorProvider provider = new ComparatorProvider();

        // method reference
        list.sort(provider::compareByScore);
        list.forEach(System.out::println);
    }
}

运行结果:

Students{name='张三', age=18, score=98}
Students{name='赵六', age=21, score=90}
Students{name='李四', age=19, score=89}
Students{name='王五', age=25, score=78}

4.引用特定类型的任意对象的实例方法

引用String类型的任意对象的compareToIgnoreCase方法实现忽略大小写排序。

String[] arr = { "Barbara", "james", "Mary", "John",
                "Patricia", "robert", "michael", "Linda" };
Arrays.sort(arr, String::compareToIgnoreCase);
List<String> list = Arrays.asList(arr);
list.forEach(System.out::println);

运行结果:

Barbara
james
John
Linda
Mary
michael
Patricia
robert

5.引用类的构造方法

在第一个例子中,将String列表转换为Integers列表,我们也可以使用Integer类的构造方法。

List<String> list = Arrays.asList("1", "2", "3");
// method reference
List<Integer> list1 = list.stream()
                .map(Integer::new).collect(Collectors.toList());
list1.forEach(System.out::println);

6.双冒号(::)运算符本质lambda表达式的一种简写

我们知道只有一个抽象方法的接口称为函数式接口,实现函数式接口通常都是使用lambda表达式来实现。 例如:

interface MyConvert{
    int parseToInteger(String s);
}
public class Java8MethodReference4 {

    public static void main(String[] args) {

        //1.lambda表达式实现方法
        MyConvert convert = (obj)->{
          return Integer.parseInt(obj);
        };

        Integer v1 = convert.parseToInteger("111");
        System.out.println(v1);

        //2.双冒号方法引用的简写方式
        convert = Integer::parseInt;
        Integer v2 = convert.parseToInteger("222");
        System.out.println(v2);
    }
}

小结:

Java中双冒号(::)运算操作符被称为方法引用,本质是lambda表达式的一种简写。

双冒号(::)运算符使用有两个大的前提条件,否则不适合使用方法引用。 - 满足lambda的相关条件,即(::)可以使用lambda表达式表示;(通常是实现函数式接口) - 只能有一条语句,且必须是调用方法的语句。

双冒号(::)运算符有以下四种方法引用: