1

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()...

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The advantage of everything "inline" is avoiding mutable local variables, which are a common cause of hard-to-trace bugs when combined with large blocks of code. A mutable local unleashes the potential of changing it at any line of code, imposing an increased cognitive load on the programmer. On the other hand, small code blocks should be preferred anyway, in which case the difference diminishes.
@Marko Topolnik: It’s hard to tell, whether doTrim is mutable, but at least it seems to originate from a distant code location, so the suspicious design is already there, while in my second example, the mutable local variable only exists because I don’t know what follow-up action to perform with the String as the question’s code is to narrow. In my code, such an action would never appear as either the source would be capable to provide the String trimmed if demanded or the follow-up action would be able to find the right boundaries for the String processing when needed.
In your first example, optionalValue is forced to be mutable; in the second case it is the s variable. OP's code involves no mutable locals in the idiom under discussion; doTrim is just an outside parameter and could very well be immutable, possibly replaced with a method invocation in real code. Also I would consider the role of trim in the question as just a simple example to motivate the idiom.
0

Two perspectives:

  1. From Java language perspective

    Both are same.

  2. From JVM byte code instruction perspective

    They are different. (x) -> x is translated to InvokeDynamic, while Function.identity() is translated to traditional InterfaceMethod.

Comments

0

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.