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

时间:2021-12-28 20:21:40

I am new in Java so please be patient.

我是Java新手所以请耐心等待。

It is common to map (convert) lists to lists. Some languages have a map method, some (C#) Select. How is this done with Java? Is a for loop the only option?

将列表(转换)列表映射到列表是很常见的。有些语言有map方法,有些(C#)选择。这是如何用Java完成的? for循环是唯一的选择吗?

I expect to be able to do something like this:

我希望能够做到这样的事情:

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

I have missed something? Please give me a starting point.

我错过了什么?请给我一个起点。

6 个解决方案

#1


I implemented something on the fly. See if this helps you. If not, use Google Collections as suggested.

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


There is no built-in way of doing this in Java - you have to write or use a helper class. Google Collections includes

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

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

This works well, but it's a bit clumsy to use, as you have to use a one-method anonymous class and a static method. This is no fault of Google Collections, it is just the nature of doing this type of task in Java.

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

Note that this lazily transforms items in the source list as needed.

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

#3


As long as customerDto extends Customer, this will work

只要customerDto扩展Customer,这将有效

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

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

Otherwise :

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

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

for (Customer cust:customers) {
  dtos.add(new CustomerDto(cust));
}

#4


There isn't yet a way to apply a mapping function like this to a Java List (or other collections). Closures, which will provide this functionality, were seriously considered for the upcoming JDK 7 release, but they have been deferred to a later release due to a lack of consensus.

还没有办法将这样的映射函数应用于Java List(或其他集合)。将在即将发布的JDK 7版本中认真考虑将提供此功能的闭包,但由于缺乏共识,它们已被推迟到稍后版本。

With current constructs, you can implement something like this:

使用当前结构,您可以实现以下内容:

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;
  }

}

#5


Personally, I find the following shorter and simpler, but if you find the functional approach simpler you could do it that way. If other Java developers might need to read/maintain the code I suggest using the approach they might feel more comfortable with.

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

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

You might find this library interesting Functional Java

您可能会发现此库有趣的功能Java

#6


Old thread, but thought I'd add that I've had good experiences with Apache Commons CollectionUtils' collect method. It's very similar to the Google Collections method above, although I haven't compared them for performance.

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

#1


I implemented something on the fly. See if this helps you. If not, use Google Collections as suggested.

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


There is no built-in way of doing this in Java - you have to write or use a helper class. Google Collections includes

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

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

This works well, but it's a bit clumsy to use, as you have to use a one-method anonymous class and a static method. This is no fault of Google Collections, it is just the nature of doing this type of task in Java.

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

Note that this lazily transforms items in the source list as needed.

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

#3


As long as customerDto extends Customer, this will work

只要customerDto扩展Customer,这将有效

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

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

Otherwise :

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

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

for (Customer cust:customers) {
  dtos.add(new CustomerDto(cust));
}

#4


There isn't yet a way to apply a mapping function like this to a Java List (or other collections). Closures, which will provide this functionality, were seriously considered for the upcoming JDK 7 release, but they have been deferred to a later release due to a lack of consensus.

还没有办法将这样的映射函数应用于Java List(或其他集合)。将在即将发布的JDK 7版本中认真考虑将提供此功能的闭包,但由于缺乏共识,它们已被推迟到稍后版本。

With current constructs, you can implement something like this:

使用当前结构,您可以实现以下内容:

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;
  }

}

#5


Personally, I find the following shorter and simpler, but if you find the functional approach simpler you could do it that way. If other Java developers might need to read/maintain the code I suggest using the approach they might feel more comfortable with.

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

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

You might find this library interesting Functional Java

您可能会发现此库有趣的功能Java

#6


Old thread, but thought I'd add that I've had good experiences with Apache Commons CollectionUtils' collect method. It's very similar to the Google Collections method above, although I haven't compared them for performance.

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