问题
Suppose we have boolean flag to turn on/off map in a stream. For example to trim or not.
Are the below examples proper solution or there is a better way to implement that?
boolean doTrim = true;
optionalValue.map(doTrim ? String::trim : (x) -> x ).get()...
or:
boolean doTrim = true;
optionalValue.map(doTrim ? String::trim : Function.identity() ).get()...
回答1:
You are over-complicating things. If you have an Optional<String> optionalValue
you can simply say:
if(doTrim) optionalValue=optionalValue.map(String::trim);
and proceed afterwards, e.g. call get
on it.
But if you are calling get()
unconditionally as in your example, you have to be confident, that the Optional
isn’t, well, optional, but present. If you know that the String
is present, you can do it even simpler:
String s=optionalValue.get();
if(doTrim) s=s.trim();
If you insist on having all the code inline, you can, of course, write it like:
(doTrim? optionalValue: optionalValue.map(String::trim)).get()
or
(doTrim? optionalValue.get(): optionalValue.get().trim())
But there is no real advantage over an ordinary if
statement here. If you have a real optional value, not knowing whether the String
is present, and don’t want to call get
immediately, I’d recommend the first version of my answer as it allows to proceed with the Optional
in any way you like. Your variant of selecting between String::trim
and an identity function may look more funky but has no real advantage over conventional programming.
回答2:
Two perspectives:
From Java language perspective
Both are same.
From JVM byte code instruction perspective
They are different.
(x) -> x
is translated to InvokeDynamic, whileFunction.identity()
is translated to traditional InterfaceMethod.
回答3:
The approach is not really functional and the boolean flag is a code smell that hints at the problem: instead of
if flag then map(foo) else map(bar)
you better pass the function that will get mapped over the optional and say
map(f)
The benefit is clear: As it stands, your code can either trim the string or do nothing. But next week, you'll want it also uppercased, or lowercased, or trimmed, reversed and uppercased in certain instances. What do you do then? Write an enum?
来源:https://stackoverflow.com/questions/27315959/java-8-conditional-map-or-map-with-identity-function