Функциональное программирование на Java

как вы можете эмулировать функциональное программирование в java, в частности, делать такие вещи, как сопоставление функции с коллекцией элементов?

map(func, new String[]{"a","b","c"});

какой наименьший многословный и неудобный способ сделать это?

Ответ 1

К сожалению, все попытки функционального программирования будут иметь некоторую часть подробного и/или неудобного для него в Java.

Самый прямой способ - предоставить интерфейс Function (например, эту форму Guava) и предоставить всевозможные методы, которые возьмите и назовите его (например, Collections#transfrom(), который делает то, что, как мне кажется, должен сделать ваш метод map()).

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

Collection<OutputType> result = Collections.transform(input, new Function<InputType,OutputType>() {
    public OutputType apply(InputType input) {
      return frobnicate(input);
    }
});

Следует отметить, что запланированная функция Lambda Java 8 сделает это значительно проще (и, возможно, даже быстрее!). Эквивалентный код в (текущей форме) lambdas будет выглядеть следующим образом:

Collection<OutputType> result = Collections.transform(input, SomeClass::frobnicate);

или более подробный, но более гибкий:

Collection<OutputType> result = Collections.transform(input, in -> frobnicate(in));

Ответ 2

Я использовал lambdaj и functionaljava для такого рода вещей. И есть, вероятно, другие...

Ответ 3

Просто оберните функцию, которую вы хотите применить в списке, с классом или интерфейсом.

public interface Func {
  Object f(Object input);
}

public void map (Func func, Object[] arr) {
  for(int i=0;i<arr.legnth;i++) {
    arr[i] = func.f(arr[i]);
  }
}

map(
  new Func() { public Object f(Object input) { return input; } };,
  new String[]{"a","b"});

Ответ 4

Как вы отмечаете, Java не предназначен для функционального программирования, и, хотя вы можете эмулировать его, вам действительно нужно это делать, даже если это более подробный и более неудобный, чем использование стандартного программирования на Java.

Возьмите пример @Joachim.

Collection<OutputType> result = Collections.transform(input, new Function<InputType,OutputType>() {
    public OutputType apply(InputType input) {
      return frobnicate(input);
    }
});

Это использует 12 символов, не считая закрытых скобок. То же самое в простой Java будет выглядеть.

List<OutputType> list = new ArrayList();
for(InputType in: input) 
    list.add(frobnicate(in));

Это использует 7 символов.

Вы можете выполнять функциональное программирование на Java, но вы должны ожидать, что он будет более подробным и неудобным, чем использование естественного стиля программирования Java.

Ответ 5

Вы можете загрузить OpenJDK 8, который планируется выпустить в следующем году, и использовать новые выражения Lambda для функционального программирования. См. http://macgyverdev.blogspot.se/2012/10/functional-programming-in-java.html для примеров того, как эти закрытия будут использоваться в API-интерфейсах Collection и как они сравниваются с решениями до Java 8, такими как Guava и LambdaJ.