java中在什么地方可以使用方法引用?是在使用lambda的地方吗?

108 阅读3分钟

背景

在练习方法引用的时候,突然想到一个问题,方法引用是什么时候用那?用在哪里那?刚开始以为只是用在lambda出现的地方,后来查询了下,任何使用函数对象的地方,都可以使用,下面是查询的回答,在此做个记录。

查询结果

在Java中,方法引用(Method References)是一种简洁的方式,用来直接引用已经存在的方法,而不是通过Lambda表达式来定义匿名函数。方法引用可以用于任何接受函数式接口作为参数的地方,而不仅仅是Lambda表达式的上下文。函数式接口是指只有一个抽象方法的接口。

方法引用的四种形式

  1. 静态方法引用ClassName::staticMethod
  2. 特定对象的实例方法引用instance::instanceMethod
  3. 任意对象的实例方法引用Type::instanceMethod
  4. 构造方法引用ClassName::new

使用场景

  • Stream API:这是最常见使用方法引用的场景之一。当你需要对流中的元素执行某种操作时,如果这个操作正好对应于一个已有的方法,那么你可以使用方法引用来代替Lambda表达式。

    List<String> strings = Arrays.asList("apple", "banana", "orange");
    strings.stream().map(String::toUpperCase).forEach(System.out::println);
    
  • 事件处理:在GUI编程中,如使用Swing或JavaFX时,可以将方法引用用于事件处理器。

    button.setOnAction(event -> System.out.println("Button clicked!"));
    // 可以用方法引用替代:
    button.setOnAction(this::handleButtonClick);
    
  • 多线程编程:当创建新线程并指定其运行的任务时,如果任务是一个已有方法,可以直接使用方法引用。

    new Thread(new Runnable() {
        @Override
        public void run() {
            doTask();
        }
    }).start();
    // 可以用方法引用替代:
    new Thread(this::doTask).start();
    
  • Comparator:当你需要创建比较器时,方法引用也可以简化代码。

    List<Person> people = ...;
    people.sort(Comparator.comparing(Person::getName));
    
  • 工厂模式:当你有一个工厂方法用于创建对象实例时,可以使用构造方法引用。

    Supplier<MyClass> supplier = MyClass::new;
    MyClass instance = supplier.get();
    

Lambda表达式与方法引用

方法引用实际上是Lambda表达式的一种更简洁的形式。如果你发现你的Lambda表达式只是简单地调用了一个方法,那么通常可以将其替换为方法引用。例如:

// Lambda 表达式
strings.forEach(s -> System.out.println(s));

// 方法引用
strings.forEach(System.out::println);

两者是等价的,但方法引用更加简洁,并且有时可读性更好。不过,只有当Lambda表达式体仅包含一个方法调用时,才能用方法引用来替换它。如果Lambda表达式包含了更多的逻辑,比如条件判断、循环等,则不能使用方法引用。

总结

方法引用可以在任何接受函数式接口作为参数的地方使用,这包括但不限于Lambda表达式的上下文。它们提供了一种更简洁、更易读的方式来引用现有方法,尤其是在你只需要执行一个方法调用的情况下。