Java基础之方法引用(JDK1.8新特性)

简介: 方法引用是通过方法的名字来指向一个方法,方法引用可以是语言更紧凑简洁,减少冗余代码。方法引用使用一对冒号 ::

方法引用

方法引用是通过方法的名字来指向一个方法,方法引用可以是语言更紧凑简洁,减少冗余代码。

方法引用使用一对冒号 ::

有现成的方法可以完成你想要传递到其他代码的某个动作,

1.例如假设你希望只要出现一个定时器事件就打印这个事件对象,你可以调用Timer timer = new Timer(1000, even -> System.out.println(even))

你也可以直接把println方法传递到Timer构造器,具体的做法是:

Timer timer1 = new Timer(1000,System.out::println)

表达式System.out::println 是一个方法引用,它等价于lambda表达式x->System.out.println(x)


2. 假如你想对字符串排序,而不考虑字母的大小写,可以传递一下方法表达式:

Arrays.sort(strings,String::compareToIgnore)


从这些例子可以看出,要用 :: 操作符分隔方法名与对象或类名。主要有3种情况:


object::instanceMethod

Class::staticMethod

Class::instanceMethod

在前2种情况中,方法引用等价于提供方法参数的lambda表达式。前面已经提到,System.out.println等价于

x->System.out.println(x)。类似得,Math::pow等价于(x,y)->Math.pow(x,y)

对于第3种情况,第1个参数会成为方法的目标,例如:String::compareToIgnoreCase等同于(x,y)->x.compareToIgnoreCase(y)

实例如下:

@FunctionalInterface
public interface Supplier<T> {
    T get();
    class Car{
        /**
         //Supplier是jdk1.8的接口,这里和lambda一起使用了
         * @param supplier
         * @return
         */
        public static Car create(final Supplier<Car> supplier) {
            return supplier.get();
        }
        public static void collide(final Car car) {
            System.out.println("collided " + car.toString());
        }
        public void follow(final Car another) {
            System.out.println("Following the " + another.toString());
        }
        public void repair() {
            System.out.println("Repaired " + this.toString());
        }
        public static void main(String[] args) {
            //构造器引用,它的语法是Class::new,或者更一般的Class<T>::new实例
            final Car car = Car.create(Car::new);
            final List<Car> cars = Arrays.asList(car);
            //静态方法引用:它的语法是Class::static_method,实例如下:
            cars.forEach(Car::collide);
            //特定类的任意对象的方法引用:它的语法是Class::method
            cars.forEach(Car::repair);
            //特定对象的方法引用:它的语法是instance::method
            final Car police = Car.create(Car::new);
            cars.forEach(police::follow);
        }
    }
}

再谈Comparator

Comparator 接口包含很多方便的静态方法来创建比较器。这些方法可以用于lambda表达式或者方法引用


静态comparing 方法取一个"键提取器"函数,它将类型T映射为一个课比较的类型(如String)。对要比较的对象


应用这个函数,然后对返回的键完成比较。例如,假设有一个Person对象数组,可以如下按名字对这些对象排序:

Arrays.sort(people,Comparator.comparing(Person::getName))


我们来看一个完整的例子:

public class PersonCompartor {
    public static void main(String[] args) {
        People person = new People();
        person.setId(111);
        person.setName("zhangsan");
        People person1 = new People();
        person1.setId(12);
        person1.setName("zhangsan");
        People person2 = new People();
        person2.setId(31);
        person2.setName("an三");
        People person3 = new People();
        person3.setId(21);
        person3.setName("an一11111111");
        People[] peopleArray = new People[]{person,person1,person2,person3};
        //1、按照人名排序
        Arrays.sort(peopleArray, Comparator.comparing(People::getName));
        System.out.println("第一次排序结果:"+JSON.toJSONString(peopleArray));
        //2、人名相同的情况下,按照id排序
        Arrays.sort(peopleArray,Comparator.comparing(People::getName).thenComparing(People::getId));
        System.out.println("第二次排序结果:"+JSON.toJSONString(peopleArray));
        //3、根据人名长度完成排序:,提取了的键指定一个比较器
        Arrays.sort(peopleArray, Comparator.comparing(People::getName, (s, t) -> Integer.compare(s.length(), t.length())));
        System.out.println("第三次排序结果:"+JSON.toJSONString(peopleArray));
        //4、第三种方法的变体
        Arrays.sort(peopleArray,Comparator.comparing(p->p.getName().length()));
        System.out.println("第四次排序结果(同第三次):"+JSON.toJSONString(peopleArray));
    }
}

运行结果是:

第一次排序结果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":111,"name":"zhangsan"},{"id":12,"name":"zhangsan"}]
第二次排序结果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"}]
第三次排序结果:[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]
第四次排序结果(同第三次):[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]

参考

Java 8 方法引用


相关文章
|
18天前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
24天前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
60 9
|
4天前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
9天前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
27 7
|
13天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
33 5
|
17天前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
30 4
|
17天前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
22 4
|
15天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
21 1
|
15天前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
36 1
|
24天前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
51 1