Result-Lazy provides lazy versions of Result objects
This library provides lazy versions of Result objects.
Lazy results encapsulate expensive operations that can be entirely omitted (as an optimization). These result can be manipulated just like any other, but the encapsulated operation will not be executed unless there’s an actual check for success/failure.
Artifact coordinates:
com.leakyabstractions
result-lazy
0.6.0.1
Maven Central Repository provides snippets for different build tools to declare this dependency.
To create a lazy result, all we need to do is invoke static method LazyResults.ofSupplier()
:
/* Create new lazy result */
Supplier<Result<Integer, String>> supplier = () -> success(123);
Result<Integer, String> lazy = LazyResults.ofSupplier(supplier); // Just like that!
As you can see, a supplier can simply return a fixed result. However, lazy results are more useful when they encapsulate an actual method that either takes a long time to execute or potentially uses up scarce resources.
/* Represents the operation we could omit */
Result<Long, Exception> expensiveCalculation(AtomicLong timesExecuted) {
long counter = timesExecuted.incrementAndGet();
return success(counter);
} // In this example, we just increment and return current count
The good thing about lazy results is that they will try to defer the invocation of the given supplier as long as possible. You can manipulate them just like any other result, though.
/** The operation is omitted because the lazy result is not fully evaluated */
@Test
void should_not_execute_expensive_action() {
final AtomicLong timesExecuted = new AtomicLong();
// Given
final Result<Long, Exception> lazy = LazyResults
.ofSupplier(() -> expensiveCalculation(timesExecuted));
// When
final Result<String, Exception> transformed = lazy.mapSuccess(Object::toString);
// Then
assertNotNull(transformed);
assertEquals(0L, timesExecuted.get());
} // End
The previous test proves that a lazy result could be transformed and it kept behaving as a lazy result, which means that the expensive calculation was never executed.
On the other hand, when it comes the time to evaluate whether the operation was actually successful or failed, the lazy result will end up invoking the method.
/** The operation is executed because the lazy result is evaluated */
@Test
void should_execute_expensive_action() {
final AtomicLong timesExecuted = new AtomicLong();
// Given
final Result<Long, Exception> lazy = LazyResults
.ofSupplier(() -> expensiveCalculation(timesExecuted));
// When
final Result<String, Exception> transformed = lazy.mapSuccess(Object::toString);
final boolean success = transformed.hasSuccess();
// Then
assertTrue(success);
assertEquals(1L, timesExecuted.get());
} // End
This library adheres to Pragmatic Versioning.
Artifacts are available in Maven Central.
Here you can find the full Javadoc documentation.
We’d love to help. Check out the support guidelines.
If you’d like to contribute to this project, please start here.
This project is governed by the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
Copyright 2024 Guillermo Calvo.
This library is licensed under the Apache License, Version 2.0 (the “License”); you may not use it except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
Permitted:
Required:
Forbidden: