In general, Optional
has a restricted set of use cases and is in danger of being overrused. You can refer to this answer by Java author Brian Goetz to understand these (emphasis added):
But we did have a clear intention when adding this [java.util.Optional] feature, and it was not to be a general purpose Maybe or Some type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.
For example, you probably should never use it for something that returns an array of results, or a list of results; instead return an empty array or list. You should almost never use it as a field of something or a method parameter.
In the original example posted, Optional<Y>
is used as a method parameter so this is against Java best practices. Besides, Maybe
is idiomatic in RxJava.
Assuming you have something like the following:
class X
class Y
data class DataContent constructor(val listOfX: List<X>, val y: Y)
You could write a function like this that would seem to fit your use case:
fun zipToDataContent(maybeListOfX: Maybe<List<X>>, maybeY: Maybe<Y>): Maybe<DataContent> =
Maybe.zip<List<X>, Y, DataContent>(
maybeListOfX,
maybeY,
BiFunction { listOfX, y -> DataContent(listOfX, y) })
Tests:
@Test
fun testZipToDataContentWithRealY() {
val x = X()
val y = Y()
val maybeListOfX = Maybe.just(listOf(x))
val maybeY = Maybe.just(y)
zipToDataContent(maybeListOfX, maybeY).test()
.assertOf {
Maybe.just(DataContent(listOf(x), y))
}
}
@Test
fun testZipToDataContentWithEmptyY() {
val x = X()
val maybeListOfX = Maybe.just(listOf(x))
val maybeY = Maybe.empty<Y>()
zipToDataContent(maybeListOfX, maybeY).test()
.assertOf {
Maybe.empty<DataContent>()
}
}