3
votes

I have this code which is realized with a for loop. I wanted to write it with a .stream and .map() function. I tried using the .map() function. But unfortunately I get the following error:

Incompatible types. Required List> but 'collect' was inferred to R: no instance(s) of type variable(s) exist so that Boolean conforms to List inference variable T has incompatible bounds: equality constraints: List lower bounds: Boolean

Here is the old code:

 public Iterable<Record> findAll(final List<Long> id) {
        final List<Record> result = new LinkedList<Record>();
        final List<List<Long>> partitions = ListUtils.partition(id, 10);
        for (List<Long> partition : partitions) {
            Iterables.addAll(
                    result,
                    this.repository.findAll(partition) 
            );
        }
        return result;
    }

This is the code when I use the .map()

   public Iterable<Record> findAll(final List<Long> id) {
        final List<Record> result = new LinkedList<Record>();
        final List<List<Long>> partitions = ListUtils.partition(id, 10);

         List<List<Long>> allPartitions = partitions.stream().map(partition ->{
            return Iterables.addAll(result, this.repository.findAll(partition));
        }).collect(Collectors.toList());

        return result;
    }

Any suggestion on how I could fix this? or on what I should pay attention?

2
Try this List<List<Long>> allPartitions = partitions.stream().map(partition ->{ Iterables.addAll(result, this.repository.findAll(partition)); return result; }).collect(Collectors.toList()); - Hadi J
@HadiJ I don't see any difference with my code that I wrote, and which didn't work - dernor00
Iterables.addAll(result, this.repository.findAll(partition)); returns boolean while you need to returns List<Long> because of that it isn't compatible. so I guess you should return result although I don't familiar with guava. - Hadi J
Or like this return partitions.stream() .flatMap(partition->this.repository.findAll(partition).stream()) .collect(Collectors.toList()); - Hadi J
What does this.repository.findAll(partition) return? - Holger

2 Answers

3
votes

Assuming that this.repository.findAll(partition) returns Iterable<Record>, you can use

public Iterable<Record> findAll(final List<Long> id) {
    return ListUtils.partition(id, 10).stream()
        .flatMap(partition -> StreamSupport.stream(
                this.repository.findAll(partition).spliterator(), false))
        .collect(Collectors.toList());
}

This complicated Stream construction is only necessary when findAll returns an Iterable rather than Collection. If it returned Collection, you could simply use:

public Iterable<Record> findAll(final List<Long> id) {
    return ListUtils.partition(id, 10).stream()
        .flatMap(partition -> this.repository.findAll(partition).stream())
        .collect(Collectors.toList());
}

In that regard, you shouldn’t put the same burden on the caller of your method and consider changing the return type from Iterable<Record> to Collection<Record> or even List<Record>.

The other point to consider, is whether performing this operation in these small chunks really has any benefit, when you are retrieving all records anyway.
So why not just use return this.repository.findAll(id);

1
votes

I guess you can replase for loop with forEach:

public Iterable<Record> findAll(final List<Long> id) {
    final List<Record> result = new LinkedList<Record>();
    final List<List<Long>> partitions = ListUtils.partition(id, 10);
    partitions.forEach(partition -> Iterables.addAll(result, this.repository.findAll(partition)));
    return result;
}