1

Given the code fragment below, how would I use Vavr immutable lists or streams? I can't as a local variable since there is no way to mark it final. I don't want to promote List<CurvePoint> points to a class member.

import io.vavr.collection.List;

private RemoteFileTemplate template;

public <T> List<T> loadObjects(Class<T> type, InputStream stream) {...}

public List<CurvePoint> getCurvePoints(String path, FTPFile file) {
    final List<CurvePoint> points = List.empty();
    template.get(path + "/" + file.getName(), s -> {
        // The final local variable points cannot be assigned. It must be blank and not using a compound assignment
        points = points.appendAll(loadObjects(CurvePoint.class, s));
    });

    return points;
}

public class RemoteFileTemplate<F> implements RemoteFileOperations<F>, InitializingBean, BeanFactoryAware {
    public boolean get(final String remotePath, final InputStreamCallback callback) {...}
hyiger
  • 37
  • 6
  • You should either refactor your code and change the `InputStreamCallback` to some function type, map that function over your results and return the mapped results or use a mutable collection to collect your results instead of the vavr list. Immutable collections are not a good fit for the use case you're trying to use them for. You could also wrap your `points` list with an `AtomicReference` and update the reference with `ref.set(...)` but that would be a pretty ugly hack as well. – Nándor Előd Fekete Dec 12 '17 at 23:37
  • I can't refactor InputStreamCallback because the RemoteFileTemplate class is part of the Spring framework. I switched to java.util mutable collections for now since everything I came up with is ugly – hyiger Dec 13 '17 at 01:49
  • Well, then the spring API forces mutability upon you, so you have not much choice. Mutable collection is the way to go in this case, `AtomicReference` would be more ugly. – Nándor Előd Fekete Dec 13 '17 at 03:13

1 Answers1

1

This is the problem with the void doStuff(Callback<Whatever> callback) syntax: hard to unit test, and tightly couples the emitter (RemoteFileTemplate) with the consumer (Callback code).

If instead the signature was CompletableFuture<Whatever> doStuff() then you could freely write immutable code (with Vavr or anything else). Then you could write something in the spirit of return List.ofAll(template.get(path + "/" + file.getName()).get()) for synchronous code, or return template.get(path + "/" + file.getName()).thenApply(List::ofAll) for asynchronous code.

Sir4ur0n
  • 1,753
  • 1
  • 13
  • 24