Я хотел бы легко преобразовать коллекцию (список) объектов класса A в коллекцию объектов класса B, как это делает функция отображения Python. Есть ли какая-то "известная" реализация этой (какой-то библиотеки)? Я уже искал его в Apache commons-lang, но не повезло.
Есть ли эквивалент Java для функции отображения Python?
Ответ 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.
Ответ 4
Можно взглянуть на библиотеку Google Guava:
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Maps.html
Ответ 5
Вы можете попробовать guava, но вы, скорее всего, обнаружите, что если вы используете анонимный класс, это будет сложнее и длиннее, чем просто использовать цикл.
List<OldType> list1 =
List<NewType> list2 = new ArrayList<NewType>(list1.size());
for(OldType element: list1);
list2.add(transform(element));
Стоит вспомнить, что Java не является функциональным языком, и часто лучше просто использовать цикл. Возможно, когда Java закрывает... вздох.
Ответ 6
Посмотрите lambdaj и метод конвертации
Ответ 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 и вызывая карту метода в списке.