I've have a method that takes String
as an input and should also return a String
.
The following ASCII art presents the logical flow:
Option<A> optA = finder.findA(input);
optA
/\
isEmpty() / \ isDefined()
/ \
"ERR_1" Option<B> optB = finder.findB(optA.get().bid);
/ \
isEmpty() / \ isDefined()
/ \
"ERR_2" opt2.get().id
Basically for given input
I'm looking for A
object which is returned wrapped in an Option
. Then is A
is present I'm looking for B
- wrapped in an Option
too, otherwise return ERR_1
. Then if B
is present return it's id, otherwise return ERR_2
.
I'm wondering how it could be implemented using optionals (or pattern matching maybe?) in a nice and concise way (without any ifology) - possibly in one-liner.
Could anyone please suggest something?
Source code to try out can be found here.
It looks like you have 3 possible exit points:
You can achieve this by doing this with Javaslang:
optA
.map(a -> finder.findB(a.bid)
.map(b -> b.bid)
.getOrElse("ERR_2"))
.getOrElse("ERR_1");
If optA
is empty, we will jump straight to orElse("ERR_1")
If optA
is not empty, we are using the value stored inside for getting value b.bid
or "ERR_2"
in case of optB
emptiness.
Also, in pure Java 8, it would look like this:
optA
.map(a -> finder.findB(a.bid)
.map(b -> b.bid)
.orElse("ERR_2"))
.orElse("ERR_1");
Since you're using javaslang, Try
seems to be a better choice because it propagates the error throught the chain, while Option only propagates its "emptiness".
If you can change findA
and findB
to return Try
you get:
Try<B> b = finder.findA(input)
.flatMap(a -> finder.findB(a.bid))
If you can't, then:
Try<B> b = finder.findA(input).toTry(() -> new Exception("ERR_1"))
.flatMap(a -> findB(a.bId).toTry(() -> new Exception("ERR_2")))
That gets a tentative B
, I'm unsure if you want to collapse the valid value and the error into the same value, if that's the case then:
String value = b.getOrElseGet(Throwable::getMessage)
If you have an issue with creating pointless exceptions, you can use an Either
in each of the find operations, where the left value is your error type. That seems to model the problem better, but may have the downside of longer type signatures, depending on how you split up the expressions.
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