2016-04-26 8 views
2

Ich habe zwei einfache Klasse ImageEntity und AbbildungslisteJava 8 Stream api wie Liste zu sammeln, um Objekt

wie Ergebnisliste ImageEntity sammeln, um Abbildungsliste?

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

Klasse

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

und

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

} 

Es ist keine elegante Lösung

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

Es wurde eine Lösung durch collectingAndThen sein kann?

was sonst noch Ideen?

Antwort

2

Da ImageList aus einem List<ImageEntity> konstruiert werden, können Sie 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)); 

Auf einem separaten Notiz, Sie müssen nicht die geschweiften Klammern in Ihrem Lambda-Ausdruck verwenden. Sie können file -> new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName())

+0

Gut:

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

Sie dann wie folgt verwenden können! sehr elegant! Vielen Dank! – Atum

1

verwenden, können Sie unten auch die Kehrseite

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

Das ist wirklich seltsam, wie Collectors.toList() Object statt Liste der Objekte zurückgibt. Kannst du bitte erklären ? – Mitchapp

+0

Es ist ein Fehler meinerseits, ich betrachtete die 'ImageList' als' List '. Wir sollten etwas wie '.collect (converttoImageList());' haben –

1

Der collectingAndThen Ansatz versuchen hat, eine Liste erstellen und kopieren sie dann.

Wenn Sie etwas mehr wiederverwendbar als Ihr ursprüngliches collect Beispiel mögen, und dass, wie Ihr Beispiel nicht tut eine zusätzliche Kopie im collectingAndThen Sammler beenden, können Sie die drei Parameter der collect nehmen und machen Funktion ähnlich Collectors.toList(), die direkt auf Ihre Abbildungsliste, wie diese sammelt:

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