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?

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

Sign up to request clarification or add additional context in comments.

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

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

Comments

Your Answer

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.