2016-04-26 6 views
2

Я два простых класс ImageEntity и ImageListJava 8 потока апи как собрать список для объекта

как собрать список результатов ImageEntity в ImageList?

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

На отдельной ноте, вы не должны использовать фигурные скобки в вашем лямбда-выражения. Вы можете использовать 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() возвращает объект вместо списка объектов. Вы можете объяснить, пожалуйста ? – 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());