Say I have a currency rates loader returning isLoaded=true
result only when all the rates are loaded successfully:
//List<String> listFrom = Stream.of("EUR", "RUB").collect(toList());
//List<String> listTo = Stream.of("EUR", "CNY").collect(toList());
boolean isLoaded = true;
final FixerDataProvider httpProvider = new FixerDataProvider(maxAttempts);
final List<CurrencyRatePair> data =
listFrom.stream()
.flatMap(from -> {
final List<CurrencyRatePair> result = httpProvider.findRatesBetweenCurrencies(from, listTo);
if (Objects.isNull(result) || result.size() == 0) {
isLoaded = false; //!!!Not working as ineffectively final!!!
}
return result.stream();
}).collect(Collectors.toList());
if (!isLoaded) {
return false;
}
// do smth with loaded data
return true;
Assignment isLoaded = false;
inside lambda function is not allowed when isLoaded
variable is not final or effectively final.
Which is the most elegant solution to set/drop boolean flag inside lambda expressions?
What do you think about AtomicBoolean and set(false) method as a possible approach?
The answer is it depends. I have seen cases where using a lambda was slower and where it was faster. I have also seen that with newer updates you get more optimal code.
Consider lambda expression account -> true . The compiler verifies that the lambda matches Predicate<T> 's boolean test(T) method, which it does--the lambda presents a single parameter ( account ) and its body always returns a Boolean value ( true ). For this lambda, test() is implemented to execute return true; .
The not operator is a logical operator, represented in Java by the ! symbol. It's a unary operator that takes a boolean value as its operand. The not operator works by inverting (or negating) the value of its operand.
Lambda expressions can be stored in variables if the variable's type is an interface which has only one method. The lambda expression should have the same number of parameters and the same return type as that method. Java has many of these kinds of interfaces built in, such as the Consumer interface (found in the java.
You may be better off with an old-style loop, as others have suggested. It does feel like a bit of a programming faux pas to write lambdas with side-effects, but you're likely to find an equal number of developers who think it's fine too.
As for getting this particular lambda-with-side effects working, making isLoaded
into an AtomicBoolean
is probably your best bet. You could achieve the same effect by making isLoaded
a boolean[]
of size 1, but that seems less elegant than going with AtomicBoolean
to me.
But seriously, try using an old-school loop instead too and see which one you like better.
If you use parallel stream, you must use AtomicBoolean
. Because boolean[1]
may not be safe in parallel
scenario.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With