Java: есть ли функция карты? - PullRequest
       0

Java: есть ли функция карты?

132 голосов
/ 11 октября 2010

Мне нужна функция map .Уже есть что-то подобное в Java?

(Для тех, кто задается вопросом: я, конечно, знаю, как реализовать эту тривиальную функцию сам ...)

Ответы [ 6 ]

88 голосов
/ 08 января 2014

Начиная с Java 8, в JDK есть несколько стандартных опций:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

См. java.util.Collection.stream() и java.util.stream.Collectors.toList().

84 голосов
/ 11 октября 2010

В JDK отсутствует понятие функции с java 6.

Guava имеет интерфейс Function и
Collections2.transform(Collection<E>, Function<E,E2>)
метод обеспечивает необходимую функциональность.

Пример:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

Выход:

[a, 14, 1e, 28, 32]

В наши дни в Java 8 фактически есть функция map, поэтому я, вероятно, написал бы код более кратко:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);
26 голосов
/ 11 октября 2010

Существует замечательная библиотека под названием Функциональная Java , которая обрабатывает многие вещи, которые вы хотели бы иметь в Java, но этого не происходит. Опять же, есть еще один замечательный язык Scala, который делает все, что должен был делать Java, но при этом не совместим ни с чем написанным для JVM.

9 голосов
/ 31 мая 2013

Будьте очень осторожны с Collections2.transform() из гуавы.Самым большим преимуществом этого метода является также его самая большая опасность: его лень.

Посмотрите документацию Lists.transform(), которая, на мой взгляд, применима также к Collections2.transform():

Функцияприменяется лениво, вызывается при необходимости.Это необходимо для того, чтобы возвращаемый список был представлением, но это означает, что функция будет применяться много раз для массовых операций, таких как List.contains (java.lang.Object) и List.hashCode ().Чтобы это работало хорошо, функция должна быть быстрой.Чтобы избежать отложенной оценки, когда возвращаемый список не должен быть представлением, скопируйте возвращенный список в новый список по вашему выбору.

Также в документации Collections2.transform() упоминается, что вы получаетев режиме реального времени это изменение в исходном списке влияет на преобразованный список.Такое поведение может привести к трудным для отслеживания проблемам, если разработчик не понимает, как это работает.

Если вам нужна более классическая «карта», она будет запускаться только один раз, а затемвам лучше с FluentIterable, также из Гуавы, в которой есть операция, которая намного проще.Вот пример Google для этого:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform() вот метод карты.Он использует ту же функцию <> «обратные вызовы», что и Collections.transform().Список, который вы получаете, доступен только для чтения, используйте copyInto(), чтобы получить список для чтения и записи.

В противном случае, конечно, когда java8 выйдет с лямбдами, это будет устаревшим.

2 голосов
/ 04 декабря 2012

Это еще одна функциональная библиотека, с которой вы можете использовать карту: http://code.google.com/p/totallylazy/

sequence(1, 2).map(toString); // lazily returns "1", "2"
1 голос
/ 17 октября 2018

Хотя это старый вопрос, я хотел бы показать другое решение:

Просто определите свою собственную операцию с использованием обобщенных java и потоков java 8:

public static <S, T> List<T> mapAll(Collection<S> collection, Function<S, T> mapper) {
   return collection.stream().map(mapper).collect(Collectors.toList());
}

Чем вы можете написать такой код:

List<String> hex = mapAll(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
...