Java 8流api如何收集List to Object

时间:2016-04-26 05:11:39

标签: lambda java-8 java-stream collect collectors

我有两个简单的类ImageEntity和ImageList

如何将结果列表ImageEntity收集到ImageList?

class Foo()
{
  public Foo(int id, string name)
  {
      this.Id = id;
      this.Name = name;
  }
  public int Id { get; set; }
  public string Name { get; set; }
}

class A
{
  public A()
  {
      this.dynamicList.Add(new Foo(1, "One"));
      this.dynamicList.Add(new Foo(2, "Two"));
      this.dynamicList.Add(new Foo(3, "Three"));

      b = B();
      b.Run();
  }
    public List<Foo> dynamicList = new List<Foo>();
}

class B 
{
  public void Run()
  {
      while(true)
      {
          int id;
            string name;

          // some code goes here that gets the value of id 2
          id = 2;

          // I need to convert the value of '2' to 'Two'

      }
  }
}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<RelativeLayout
    android:id="@+id/rel1"
    android:layout_width="200dp"
    android:layout_height="match_parent"
    android:layout_alignParentEnd="true"
    android:background="#7F000000"
    android:gravity="center">

    <View
        android:id="@+id/view"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:background="#00FF00" />

    <View
        android:id="@+id/view2"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_below="@+id/view"
        android:background="#00FF00" />


</RelativeLayout>

<RelativeLayout
    android:id="@+id/rel3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true">

    <RelativeLayout
        android:id="@+id/rel2"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="55dp"
        android:background="#7F0000FF">

    </RelativeLayout>
</RelativeLayout>

List<File> files = listFiles();
        ImageList imageList = files.stream().map(file -> {
            return new ImageEntity(
                                   file.getName(), 
                                   file.lastModified(), 
                                   rootWebPath + "/" + file.getName());
        }).collect(toCollection(???));

这不是一个优雅的解决方案

public class ImageEntity {
private String name;
private Long lastModified;
private String url;
 ...
}

它可以通过收集和解决方案来解决?

还有什么想法?

3 个答案:

答案 0 :(得分:7)

由于ImageList可以从List<ImageEntity>构建,因此您可以使用Collectors.collectingAndThen

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.collectingAndThen;

ImageList imgList = files.stream()
    .map(...)
    .collect(collectingAndThen(toList(), ImageList::new));

另外,您不必在lambda表达式中使用花括号。您可以使用file -> new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName())

答案 1 :(得分:1)

你也可以在下面试试

ImageList imgList = new ImageList (files.stream().
  .map(file -> { return new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName()) })
  .collect(Collectors.toList()));

答案 2 :(得分:1)

collectAndThen方法有创建列表然后复制它的缺点。

如果您想要比最初的collect示例更可重用的内容,并且像您的示例一样,不会在collectingAndThen收集器中执行额外的副本,那么可以使用collect的三个参数,并创建一个类似于Collectors.toList()的函数,直接收集到您的ImageList,如下所示:

public static Collector<ImageEntity,?,ImageList> toImageList() {
    return Collector.of(ImageList::new, (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2));
}

然后您可以像这样使用它:

ImageList imgList = files.stream().
    .map(file -> new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName()))
    .collect(toImageList());