Unwrapping Values
How to get values out of Result objects
In essence, a Result
object is just a container that wraps a success or a failure value for us. Therefore, sometimes you are going to want to get that value out of the container.
Unwrapping Success
The most basic way to retrieve the success value wrapped inside a result is by using Result::getSuccess
. This method will return an optional success value, depending on whether the result was actually successful or not.
@Test
void testGetSuccess() {
// Given
Result<?, ?> result1 = success("SUCCESS");
Result<?, ?> result2 = failure("FAILURE");
// Then
Optional<?> success1 = result1.getSuccess();
Optional<?> success2 = result2.getSuccess();
// Then
assertEquals("SUCCESS", success1.get());
assertTrue(success2::isEmpty);
}
Unwrapping Failure
Similarly, we can use Result::getFailure
to obtain the failure value held by a Result
object.
@Test
void testGetFailure() {
// Given
Result<?, ?> result1 = success("SUCCESS");
Result<?, ?> result2 = failure("FAILURE");
// Then
Optional<?> failure1 = result1.getFailure();
Optional<?> failure2 = result2.getFailure();
// Then
assertTrue(failure1::isEmpty);
assertEquals("FAILURE", failure2.get());
}
Unlike Optional::get
, these methods are null-safe. However, in practice, we will not be using them frequently. Especially, since there are more convenient ways to get the success value out of a result.
Using Alternative Success
We can use Result::orElse
to provide an alternative success value that must be returned when the result is unsuccessful.
@Test
void testGetOrElse() {
// Given
Result<String, String> result1 = success("IDEAL");
Result<String, String> result2 = failure("ERROR");
String alternative = "OTHER";
// When
String value1 = result1.orElse(alternative);
String value2 = result2.orElse(alternative);
// Then
assertEquals("IDEAL", value1);
assertEquals("OTHER", value2);
}
Mapping Failure
The Result::orElseMap
method is similar to Optional::orElseGet
, but it takes a mapping Function
instead of a Supplier
. The function will receive the failure value to produce the alternative success value.
@Test
void testGetOrElseMap() {
// Given
Result<String, Integer> result1 = success("OK");
Result<String, Integer> result2 = failure(1024);
Result<String, Integer> result3 = failure(-256);
Function<Integer, String> mapper = x -> x > 0 ? "HI" : "LO";
// When
String value1 = result1.orElseMap(mapper);
String value2 = result2.orElseMap(mapper);
String value3 = result3.orElseMap(mapper);
// Then
assertEquals("OK", value1);
assertEquals("HI", value2);
assertEquals("LO", value3);
}
Streaming Success or Failure
Finally, we can use Result::streamSuccess
and Result::streamFailure
to wrap the value held by an instance of Result
into a possibly-empty Stream
object.
@Test
void testStreamSuccess() {
// Given
Result<?, ?> result1 = success("Yes");
Result<?, ?> result2 = failure("No");
// When
Stream<?> stream1 = result1.streamSuccess();
Stream<?> stream2 = result2.streamSuccess();
// Then
assertEquals("Yes", stream1.findFirst().orElse(null));
assertNull(stream2.findFirst().orElse(null));
}
@Test
void testStreamFailure() {
// Given
Result<?, ?> result1 = success("Yes");
Result<?, ?> result2 = failure("No");
// When
Stream<?> stream1 = result1.streamFailure();
Stream<?> stream2 = result2.streamFailure();
// Then
assertNull(stream1.findFirst().orElse(null));
assertEquals("No", stream2.findFirst().orElse(null));
}
Conclusion
We explored various ways to retrieve values from results. Using these methods you can efficiently access the underlying data within a Result object, whether it's a success or a failure.
Last updated
Was this helpful?