在Java中将一个列表映射到另一个列表的最优雅方法是什么?

时间:2009-05-14 16:17:57

标签: java

我是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 个答案:

答案 0 :(得分:5)

在Java中没有内置的方法 - 您必须编写或使用帮助程序类。 Google Collections包括

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

这很好用,但使用起来有点笨拙,因为你必须使用单方法匿名类和静态方法。这不是Google Collections的错,它只是在Java中执行此类任务的本质。

请注意,这会根据需要懒惰地转换源列表中的项目。

答案 1 :(得分:4)

我实时实施了一些东西。看看这对你有帮助。如果没有,请按照建议使用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 :(得分:2)

只要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));
}

答案 3 :(得分:0)

还没有办法将这样的映射函数应用于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;
  }

}

答案 4 :(得分:0)

就个人而言,我发现以下更短更简单,但如果您发现功能方法更简单,您可以这样做。如果其他Java开发人员可能需要阅读/维护代码,我建议使用这种方法,他们可能会感觉更舒服。

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

您可能会发现这个图书馆很有趣Functional Java

答案 5 :(得分:0)

旧线程,但我想补充一点,我对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