10

I have two simple class ImageEntity and ImageList

how to collect result list ImageEntity to ImageList ?

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

class

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

and

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

It's not an elegant solution

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

It can be a solution through collectingAndThen ?

what else have any ideas?

Misha
28.3k7 gold badges66 silver badges83 bronze badges
asked Apr 26, 2016 at 5:11

3 Answers 3

18

Since ImageList can be constructed from a List<ImageEntity>, you can use 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));

On a separate note, you don't have to use the curly braces in your lambda expression. You can use file -> new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName())

answered Apr 26, 2016 at 5:18

1 Comment

Good ! very elegant!Thank you very much!
1

you can try below also

ImageList imgList = new ImageList (files.stream().
 .map(file -> { return new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName()) })
 .collect(Collectors.toList()));
answered Apr 26, 2016 at 8:47

2 Comments

That's really weird, how Collectors.toList() returns Object instead of list of objects. Can you explain please ?
Its an error on my part , I considered the ImageList as List<Images> . We should have something like .collect(converttoImageList());
1

The collectingAndThen approach has the downside of creating a list and then copying it.

If you'd like something more reusable than your initial collect example, and that, like your example, doesn't end doing an extra copy in the collectingAndThen collector, you can take the three parameters of the collect and make a function similar to Collectors.toList() that collects straight to your ImageList, like this:

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

You could then use it like this:

ImageList imgList = files.stream().
 .map(file -> new ImageEntity(file.getName(), file.lastModified(), rootWebPath + "/" + file.getName()))
 .collect(toImageList());
answered Apr 27, 2016 at 5:50

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.