3

I have an existing api which uses java.util.Collection when returning values. I would like to use those values in later parts of my program with Vavr but I don't want to use the eager methods like List.ofAll (because I do not want to traverse those Collection objects twice). My use case is something like this:

List<Product> filter(java.util.Collection products) {
    return List.lazyOf(products).filter(pred1);
}

Is it possible?

rattaman
  • 506
  • 3
  • 15
  • This question is not clear for me. What are you worrying about precisely? What do you mean by _interfere with the whole idea of immutability_? Give an example. – Nándor Előd Fekete Jun 22 '18 at 13:19
  • Will this “list” only be used/traversed once? If so you want to return a `Stream`. Your stream can include a `filter(...)`. The stream will not be traversed until the caller uses a terminal operation on the stream. – AJNeufeld Jun 22 '18 at 13:29
  • Like I said, I want to use the Vavr List in later parts of the program so simply using Java Stream api is not really what I want. My goal is to avoid the overhead of creating (eagerly) the Vavr list from the products Collection. I reckon that filter will create a new list either way, so the initial copying of the list (by List.ofAll) is unnecessary (from my perspective, but maybe not from Vavr perspective). – rattaman Jun 22 '18 at 14:13

2 Answers2

2

Since the input collection to the method is a java Collection, you cannot rely on immutability, so you need to process the values contained in the collection right away. You cannot defer this to a later point in time as there is no guarantee the passed collection remains unchanged.

You can minimize the number of vavr Lists built by doing the filtering on an iteration of the passed collection, then collecting the result to a List.

import io.vavr.collection.Iterator;
import io.vavr.collection.List;
...

List<Product> filter(Collection<Product> products) {
    return Iterator.ofAll(products)
        .filter(pred1)
        .collect(List.collector());
}
Nándor Előd Fekete
  • 6,988
  • 1
  • 22
  • 47
  • This is exactly what I'm looking for. I think they should mention it in their Interoperability chapter of their docs. Thanks. – rattaman Jun 22 '18 at 18:11
0

There is a Lazy class in vavr. You might want to use it.

Lazy<Option<Integer>> val1 = Lazy.of(() -> 1).filter(i -> false);
kucing_terbang
  • 4,991
  • 2
  • 22
  • 28
  • Using Lazy here will simply produce a Value with the list as an element. Filter will receive the whole list as an argument and not its elements. Lazy.of(() -> Arrays.asList("a","b","c")).forEach(e -> System.out.println(e)); – rattaman Jun 22 '18 at 14:40