java - Return first non-null value -


i have number of functions:

string first(){} string second(){} ... string default(){} 

each can return null value, except default. each function can take different parameters. example, first take no arguments, second take in string, third take 3 arguments, etc. i'd like:

objectutils.firstnonnull(first(), second(), ..., default()); 

the problem because of function call, this eager evaluation. where'd i'd exit early, after second function (because function calls can expensive, think api calls, etc). in other languages, can similar this:

return first() || second() || ... || default() 

in java, know can like:

string value; if (value = first()) == null || (value = second()) == null ... return value; 

that's not readable imo because of == null checks.objectutils.firstnonnull() creates collection first, , iterates, okay long function gets evaluated lazily.

suggestions? (besides doing bunch of ifs)

string s = stream.<supplier<string>>of(this::first, this::second /*, ... */)                  .map(supplier::get)                  .filter(objects::nonnull)                  .findfirst()                  .orelseget(this::defaultone); 

it stops on first non-null value or else sets value returned defaultone. long stay sequential, safe. of course requires java 8 or later.

the reason why stops on first occurrence of non-null value due how stream handles each step. map intermediate operation, filter. findfirst on other side short-circuiting terminal operation. continues next element until 1 matches filter. if no element matches empty optional returned , orelseget-supplier called.

this::first, etc. method references. if static replace yourclassname::first, etc.

here example if signature of methods differ:

string s = stream.<supplier<string>>of(() -> first("takesoneargument"),                                        () -> second("takes", 3, "arguments")                                    /*, ... */)                  .map(supplier::get)                  .filter(objects::nonnull)                  .findfirst()                  .orelseget(this::defaultone); 

note supplier evaluated when call get on it. way lazy evaluation behaviour. method-parameters within supplier-lambda-expression must final or final.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -