Есть ли эквивалент Java для функции отображения Python?

Я хотел бы легко преобразовать коллекцию (список) объектов класса A в коллекцию объектов класса B, как это делает функция отображения Python. Есть ли какая-то "известная" реализация этой (какой-то библиотеки)? Я уже искал его в Apache commons-lang, но не повезло.

Ответ 1

все еще не существует

функциональное программирование будут добавлены в Java 8 - Project Lambda

Я думаю, Google Guava лучше всего подходит для ваших нужд сейчас

Ответ 2

Начиная с Java 8, это можно сделать, используя Stream API с помощью appopriate mapper Function, который мы будем использовать для преобразования наших экземпляров класса A в экземпляры класса B.

Псевдокод:

List<A> input = // a given list of instances of class A
Function<A, B> function = // a given function that converts an instance 
                          // of A to an instance of B
// Call the mapper function for each element of the list input
// and collect the final result as a list
List<B> output = input.stream().map(function).collect(Collectors.toList());

Вот конкретный пример, который преобразует List из String в List of Integer, используя Integer.valueOf(String) как функция сопоставления:

List<String> input = Arrays.asList("1", "2", "3");
List<Integer> output = input.stream().map(Integer::valueOf).collect(Collectors.toList());
System.out.println(output);

Вывод:

[1, 2, 3]

Для предыдущих версий Java вы все равно можете использовать FluentIterable из Google Guava, чтобы заменить Stream и использовать com.google.common.base.Function вместо java.util.function.Function как функцию сопоставления.

Предыдущий пример затем будет переписан следующим образом:

List<Integer> output = FluentIterable.from(input)
    .transform(
        new Function<String, Integer>() {
            public Integer apply(final String value) {
                return Integer.valueOf(value);
            }
        }
    ).toList();

Вывод:

[1, 2, 3]

Ответ 3

Существует несколько функциональных библиотек, упомянутых здесь большинство из которых, вероятно, покрывают карту:

http://www.cs.chalmers.se/~bringert/hoj/программист (включая Java 5.0 generics поддержка). Маленькая документация.

http://jakarta.apache.org/commons/sandbox/functor/не похоже, что он поддерживается, не поддерживает дженерики. маленький документация.

http://devnet.developerpipeline.com/documents/s=9851/q=1/ddj0511i/0511i.htmlбиблиотека.

http://functionalj.sourceforge.net

http://www.functologic.com/orbital/

http://jga.sourceforge.net/программирование в java (включает дженерики). Ждем больше документация, возможно, лучше организация API.

Ответ 5

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

List<OldType> list1 =
List<NewType> list2 = new ArrayList<NewType>(list1.size());
for(OldType element: list1);
   list2.add(transform(element));

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

Ответ 7

Так как Java 8, эквивалент Java для карты Python называется... map!

package stackOverflow;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


public class ListMapExample
{

    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        List<int[]> arrays = integers.stream().map(size -> new int[size])
                .collect(Collectors.toList());
        arrays.forEach(ary -> System.out.println(Arrays.toString(ary)));
    }

}

Эти примеры преобразуют список целых чисел в список массивов с соответствующим размером:

[0]
[0, 0]
[0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0, 0]

Вы также можете написать более одного оператора внутри карты:

List<String> strings = Arrays.asList("1", "2", "3", "4", "5");
Stream<int[]> arraysStream = strings.stream().map(string -> {
    int size = Integer.valueOf(string);
    int size2 = size * 2;
    return new int[size2];
});
arraysStream.map(Arrays::toString).forEach(System.out::println);

Ответ 8

Это мое решение:

public abstract class MapF<T,S>
    {
        public abstract T f(S s) throws Exception;

        public List<T> map(List<S> input) throws Exception
        {
            LinkedList<T> output = new LinkedList<T>();
            for (S s: input)
                output.add(f(s));
            return output;
        }
    }

Просто, расширяет этот класс, определяя вашу функцию f и вызывая карту метода в списке.