2016-11-05 10 views
4

Как именно вы связываете ссылки метода для экземпляров с Java 8? Пример:Ссылка на метод Java здесь не ожидается

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

getStrategy из Civilization экземпляра возвращает экземпляр объекта с Strategy, который имеет метод экземпляра getStrategyLevel.

Почему метод Comparator.comparing не возвращает компаратор с его функциональным интерфейсом, реализованным с помощью выражения лямбда?

+4

Просто используйте лямбда. –

+0

Ссылка на метод - это ссылка на метод_. Цепочка «вызывается' getStrategy() ', а затем вызывает' getStrategyLevel() 'в результате) не является методом, поэтому он не подходит для описания с помощью ссылки на метод.Если вы хотите описать произвольный пакет императивного кода, использовать lambda; метод refs - это (надеюсь, более читаемая) стенограмма, предусмотренная для специального случая, когда тело лямбда - это единственный метод, список аргументов которого соответствует точному целевому функциональному интерфейсу. –

+0

См. также: http: // stackoverflow.com/questions/24487805/lambda-expression-vs-method-reference/24493905 # 24493905 –

ответ

3

В этом случае вы должны использовать лямбда, вы не можете применить метод ссылки непосредственно:

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)); 
+0

getStrategy не является статическим методом –

+0

как бы я предоставил ссылку метода на метод экземпляра 'getStrategyLevel' через экземпляр« Стратегии », который является доступ через экземпляр «Цивилизации». Должен ли я просто использовать регулярное лямбда-выражение для компаратора? –

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

Вы не можете сделать это со ссылкой метод, вам нужно использовать лямбда-выражения или создать статический метод.

Существуют четыре вида ссылок Метод:

  1. Ссылка на статический метод как ContainingClass::staticMethodName
  2. ссылка на метод экземпляра конкретного объекта как containingObject::instanceMethodName
  3. Ссылка на метод экземпляра произвольного объекта определенного типа, как ContainingType::methodName
  4. Ссылка на конструктор как ClassName::new

Более подробную информацию о 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));