2016-04-26 87 views
2

我有两个简单的类ImageEntity和的ImageListJava的8个流API如何收集清单对象

如何收集结果列表ImageEntity到图像列表?

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

public class ImageList { 
private List<ImageEntity> list; 

public ImageList() { 
    list = new ArrayList<>(); 
} 

public ImageList(List<ImageEntity> list) { 
    this.list = list; 
} 
public boolean add(ImageEntity entity) { 
    return list.add(entity); 
} 
public void addAll(List<ImageEntity> list) { 
    list.addAll(entity); 
} 

} 

这不是一个完美的解决方案

ImageList imgList = files.stream(). 
    .map(file -> { return new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName()) }) 
    .collect(ImageList::new, (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2)); 

它可以通过collectingAndThen的解决方案?

还有什么想法?

回答

2

由于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())

+0

好!非常优雅!非常感谢! – Atum

1

你可以试试下面也

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

这真的很奇怪,Collectors.toList()如何返回Object而不是对象列表。你能解释一下吗? – Mitchapp

+0

它是我的错误,我认为'ImageList'为'List '。我们应该有'.collect(converttoImageList());' –

1

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

如果你想的东西比你最初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());