Guava: converting list <<T> to list <T> to store only current values

Is there an elegant way to use Guava to convert from a list of options to a list of existing values?

For example, the transition from

 ImmutableList.of( Optional.of("Tom"), Optional.<String>absent(), Optional.of("Dick"), Optional.of("Harry"), Optional.<String>absent() ) 

to a list containing only

 ["Tom", "Dick", "Harry"] 

One approach:

 List<T> filterPresent(List<Optional<T>> inputs) { return FluentIterable.from(inputs) .filter(new Predicate<Optional<T>>() { @Override public boolean apply(Optional<T> optional) { return optional.isPresent(); } }).transform(new Function<Optional<T>, T>() { @Override public T apply(Optional<T> optional) { return optional.get(); } }).toList(); } 

But it is verbose.

Java 8 is not an option, unfortunately.

+5
source share
4 answers

In Guava, there is a built-in method: presentInstances in Optional :

Returns the value of each present instance from the provided options to skip the appearance of absent() . Iterators are unmodified and evaluated lazily.

Example:

 List<Optional<String>> optionalNames = ImmutableList.of( Optional.of("Tom"), Optional.<String>absent(), Optional.of("Dick"), Optional.of("Harry"), Optional.<String>absent()); Iterable<String> presentNames = Optional.presentInstances(optionalNames); // lazy // copy to List if needed List<String> presentNamesList = ImmutableList.copyOf(presentNames); System.out.println(presentNamesList); // ["Tom", "Dick", "Harry"] 
+13
source

Why not do it in the old fashioned Java way:

 List<T> result = new ArrayList<T>(); for (Optional<T> optional : inputs) { if (optional.isPresent()) { result.add(optional.get()); } } return result; 
+6
source

You can hide instances of predicates behind method calls to make the code more readable:

 List<T> filterPresent(List<Optional<T>> inputs) { return FluentIterable.from(inputs).filter(present()).transform(value()).toList(); } static <T> Predicate<Optional<T>> present() { return new Predicate<Optional<T>>() { @Override public boolean apply(Optional<T> optional) { return optional.isPresent(); } }; } static <T> Function<Optional<T>, T> value() { return new Function<Optional<T>, T>() { @Override public T apply(Optional<T> optional) { return optional.get(); } }; } 

Unfortunately, there is no easier way in pre-Java-8.

0
source

If you call a method in a loop that returns Optional , and you want to create a List return values โ€‹โ€‹that are present, then you can use the toSet method on Optional in conjunction with the addAll method on List , for example:

 List<String> strings = newArrayList(); for (Long id : ids) { strings.addAll(getString(id).toSet()); } 

This is useful if you want to return a List , not the Iterable , which you get from Optional.presentInstances .

0
source

Source: https://habr.com/ru/post/1204717/


All Articles