Какой самый элегантный способ сопоставить один список другому в Java? - PullRequest
3 голосов
/ 14 мая 2009

Я новичок в Java, поэтому наберитесь терпения.

Распространено отображение (преобразование) списков в списки. В некоторых языках есть метод map, в некоторых (C #) Select. Как это делается с Java? for цикл - единственный вариант?

Я ожидаю, что смогу сделать что-то вроде этого:

List<Customer> customers = new ArrayList<Customer>();
...
List<CustomerDto> dtos = customers.convert(new Converter(){
  public convert(c) {
    return new CustomerDto();
  }
})

Я что-то пропустил? Пожалуйста, дайте мне отправную точку.

Ответы [ 6 ]

5 голосов
/ 14 мая 2009

В Java нет встроенного способа сделать это - вы должны написать или использовать вспомогательный класс. Коллекции Google включает

public static <F,T> List<T> transform(List<F> fromList,
                                  Function<? super F,? extends T> function)

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

Обратите внимание, что это лениво преобразует элементы в списке источников по мере необходимости.

4 голосов
/ 14 мая 2009

Я что-то реализовал на лету. Посмотрите, поможет ли это вам. Если нет, используйте Google Collections как предложено.

public interface Func<E, T> {
    T apply(E e);
}

public class CollectionUtils {

    public static <T, E> List<T> transform(List<E> list, Func<E, T> f) {
        if (null == list)
            throw new IllegalArgumentException("null list");
        if (null == f)
            throw new IllegalArgumentException("null f");

        List<T> transformed = new ArrayList<T>();
        for (E e : list) {
            transformed.add(f.apply(e));
        }
        return transformed;
    }
}

List<CustomerDto> transformed = CollectionUtils.transform(l, new Func<Customer, CustomerDto>() {
    @Override
    public CustomerDto apply(Customer e) {
        // return whatever !!!
    }
});
2 голосов
/ 14 мая 2009

Пока customerDto расширяет Customer, это будет работать

   List<Customer> customers = new ArrayList<Customer>();

   List<CustomerDto> dtos = new ArrayList<CustomerDto>(customers);

В противном случае:

List<Customer> customers = new ArrayList<Customer>();

List<CustomerDto> dtos = new ArrayList<CustomerDto>();

for (Customer cust:customers) {
  dtos.add(new CustomerDto(cust));
}
0 голосов
/ 30 марта 2011

Старый поток, но подумал, что добавлю, что у меня был хороший опыт использования метода сбора Apache Commons CollectionUtils. Это очень похоже на метод Google Collections, описанный выше, хотя я не сравнивал их по производительности.

http://commons.apache.org/collections/api/org/apache/commons/collections/CollectionUtils.html#collect%28java.util.Collection,%20org.apache.commons.collections.Transformer%29

0 голосов
/ 02 июня 2009

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

List<CustomerDto> dtos = new ArrayList<CustoemrDto>();
for(Customer customer: customers)
   dtos.add(new CustomerDto());

Эта библиотека может показаться вам интересной Функциональная Java

0 голосов
/ 14 мая 2009

Пока еще нет способа применить такую ​​функцию отображения к Java List (или другим коллекциям). Замыкания, которые обеспечат эту функциональность, были серьезно рассмотрены в предстоящем выпуске JDK 7, но они были отложены до более позднего выпуска из-за отсутствия консенсуса.

С текущими конструкциями вы можете реализовать что-то вроде этого:

public abstract class Convertor<P, Q>
{

  protected abstract Q convert(P p);

  public static <P, Q> List<Q> convert(List<P> input, Convertor<P, Q> convertor)
  {
    ArrayList<Q> output = new ArrayList<Q>(input.size());
    for (P p : input)
      output.add(convertor.convert(p));
    return output;
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...