这里不期望Java方法参考

时间:2016-11-05 16:27:09

标签: java lambda java-8 comparator method-reference

如何使用Java 8为实例链接方法引用?例如:

Collections.sort(civs,Comparator.comparing(Civilization::getStrategy.getStrategLevel));
getStrategy实例的

Civilization返回具有实例方法Strategy的{​​{1}}对象实例。

为什么getStrategyLevel方法没有返回带有lambda表达式实现的功能接口的比较器?

4 个答案:

答案 0 :(得分:4)

在这种情况下,您应该使用lambda,不能直接应用方法引用:

Collections.sort(civs, Collectors.comparing(c -> c.getStrategy().getStrategLevel()));

虽然,有一种方法可以在这里使用方法参考。假设你有一个像

这样的课程
class CivilizationUtils {
    public static Integer getKeyExtractor(Civilization c) {
        return c.getStrategy().getStrategLevel();
    }
}

这个问题可以像

一样解决
Collections.sort(civs, Collectors.comparing(CivilizationUtils::getKeyExtractor));

答案 1 :(得分:3)

您无法使用方法引用,您需要使用lambda表达式或创建静态方法。

有四种方法参考:

  1. 参考静态方法,例如ContainingClass::staticMethodName
  2. 引用特定对象的实例方法,如containingObject::instanceMethodName
  3. 引用特定类型的任意对象的实例方法,如ContainingType::methodName
  4. 引用构造函数,例如ClassName::new
  5. 有关method reference的更多详情。

    所以在这里,lambda expression会是:

    Collections.sort(civs, Comparator.comparing(c -> c.getStrategy.getStrategLevel()));
    

    或者如果您创建静态方法

    public static int getStrategLevel(Civilization c) {
        return c.getStrategy().getStrategLevel();
    }
    

    然后你的代码将是:

    Collections.sort(civs, Comparator.comparing(MyClass::getStrategLevel));
    

答案 2 :(得分:1)

Collections.sort(civs,Comparator.comparing(civ -> civ.getStrategy().getStrategLevel()));

答案 3 :(得分:0)

不同的示例,但是我有一个方法

void m(Predicate<String> stringPredicate)

和一个实用程序类

class Utilities {
  static boolean condition1(String s) { ... }
  static boolean condition2(String s) { ... }
  ...
}

并且我想使用返回true的谓词调用m,而Utilities.condition1返回false。 Java语法允许我编写

m(Utilities::condition1)

但不是

m(Utilities::condition1.negate())

(不幸地违反了referential transparency),编译器抱怨说:“这里不应该引用Java方法。”

我的解决方法是编写一个方法

Predicate<String> not(Predicate<String> p) {
  return p;
}

然后编写通话

m(not(Utilities::condition1))

-Java语法允许。