Scala Option.orElse equivalent for Java Optional - java

Option has the following method defined:
def orElse[B >: A](alternative : => scala.Option[B]) : scala.Option[B]
I'm trying to find something similar in Java 8. I came to this expression:
private String userId() {
return user.map(User::getUsername)
.orElse(this.userId.orElseThrow(RuntimeException::new));
}
Where user and userId are both Optional's, but somehow this crashes with RuntimeException even if user is defined.
Is there something more functional in Java then just starting making conditionals on Optional's?

What you're looking for is the Optional.or method introduced in Java 9:
public Optional<T> or​(Supplier<? extends Optional<? extends T>> supplier)

Use orElseGet:
private String userId() {
return user.map(User::getUsername)
.orElseGet(() -> this.userId.orElseThrow(RuntimeException::new));
}
When you use normal orElse, its parameter is executed before execution of orElse itself, so orElse can just return it, but cannot decide whether execute it or not. Using orElseGet you create a lambda which is executed only when the Optional is empty.

Related

Optional ifPresent otherwise call another function

I wrote code that works, however I had to create extra lines, is there a way to compress that in one line? The logic: take last page, perform searching function by regex, if not located, take the page before and perform searching function by regex
Optional<String> totalBoxesLastPage = lastPage.locate(INVOICE_TOTAL_AMOUNT_BOXES);
Optional<String> totalBoxes = totalBoxesLastPage.isPresent() ?
totalBoxesLastPage : nextToLastPage
.flatMap(p -> p.locate(INVOICE_TOTAL_AMOUNT_BOXES));
Thank you guys
You may use orElseGet with a supplier to call some function which computes the value if the optional is empty. If a value is present, it returns the value, otherwise returns the result produced by the supplying function. In your case you have to pass Supplier<String>. Moreover, your return type after unwrapping the Optional should be a String, not an Optional<String>.
String totalBoxes = totalBoxesLastPage
.orElseGet(() -> nextToLastPage.flatMap(p -> p.locate(INVOICE_TOTAL_AMOUNT_BOXES))
.orElseThrow(IllegalStateException::new));
This worked out for me , i was really blind by not seeing .or function
or(Supplier<? extends Optional<? extends T>> supplier)
public Optional<String> findBetweenTwo(Page lastPage,Optional<Page> nextToLast,Pattern pattern) {
return lastPage.locate(pattern).or(() -> nextToLast.flatMap(p -> p.locate(pattern)));
}

java 8 lambdas interface mismatch [duplicate]

I am confused by the following code
class LambdaTest {
public static void main(String[] args) {
Consumer<String> lambda1 = s -> {};
Function<String, String> lambda2 = s -> s;
Consumer<String> lambda3 = LambdaTest::consume; // but s -> s doesn't work!
Function<String, String> lambda4 = LambdaTest::consume;
}
static String consume(String s) { return s;}
}
I would have expected the assignment of lambda3 to fail as my consume method does not match the accept method in the Consumer Interface - the return types are different, String vs. void.
Moreover, I always thought that there is a one-to-one relationship between Lambda expressions and method references but this is clearly not the case as my example shows.
Could somebody explain to me what is happening here?
As Brian Goetz pointed out in a comment, the basis for the design decision was to allow adapting a method to a functional interface the same way you can call the method, i.e. you can call every value returning method and ignore the returned value.
When it comes to lambda expressions, things get a bit more complicated. There are two forms of lambda expressions, (args) -> expression and (args) -> { statements* }.
Whether the second form is void compatible, depends on the question whether no code path attempts to return a value, e.g. () -> { return ""; } is not void compatible, but expression compatible, whereas () -> {} or () -> { return; } are void compatible. Note that () -> { for(;;); } and () -> { throw new RuntimeException(); } are both, void compatible and value compatible, as they don’t complete normally and there’s no return statement.
The form (arg) -> expression is value compatible if the expression evaluates to a value. But there are also expressions, which are statements at the same time. These expressions may have a side effect and therefore can be written as stand-alone statement for producing the side effect only, ignoring the produced result. Similarly, the form (arg) -> expression can be void compatible, if the expression is also a statement.
An expression of the form s -> s can’t be void compatible as s is not a statement, i.e. you can’t write s -> { s; } either. On the other hand s -> s.toString() can be void compatible, because method invocations are statements. Similarly, s -> i++ can be void compatible as increments can be used as a statement, so s -> { i++; } is valid too. Of course, i has to be a field for this to work, not a local variable.
The Java Language Specification §14.8. Expression Statements lists all expressions which may be used as statements. Besides the already mentioned method invocations and increment/ decrement operators, it names assignments and class instance creation expressions, so s -> foo=s and s -> new WhatEver(s) are void compatible too.
As a side note, the form (arg) -> methodReturningVoid(arg) is the only expression form that is not value compatible.
consume(String) method matches Consumer<String> interface, because it consumes a String - the fact that it returns a value is irrelevant, as - in this case - it is simply ignored. (Because the Consumer interface does not expect any return value at all).
It must have been a design choice and basically a utility: imagine how many methods would have to be refactored or duplicated to match needs of functional interfaces like Consumer or even the very common Runnable. (Note that you can pass any method that consumes no parameters as a Runnable to an Executor, for example.)
Even methods like java.util.List#add(Object) return a value: boolean. Being unable to pass such method references just because that they return something (that is mostly irrelevant in many cases) would be rather annoying.

Why do Consumers accept lambdas with statement bodies but not expression bodies?

The following code surprisingly is compiling successfully:
Consumer<String> p = ""::equals;
This too:
p = s -> "".equals(s);
But this is fails with the error boolean cannot be converted to void as expected:
p = s -> true;
Modification of the second example with parenthesis also fails:
p = s -> ("".equals(s));
Is it a bug in Java compiler or is there a type inference rule I don't know about?
First, it's worth looking at what a Consumer<String> actually is. From the documentation:
Represents an operation that accepts a single input argument and
returns no result. Unlike most other functional interfaces, Consumer
is expected to operate via side-effects.
So it's a function that accepts a String and returns nothing.
Consumer<String> p = ""::equals;
Compiles successfully because equals can take a String (and, indeed, any Object). The result of equals is just ignored.*
p = s -> "".equals(s);
This is exactly the same, but with different syntax. The compiler knows not to add an implicit return because a Consumer should not return a value. It would add an implicit return if the lambda was a Function<String, Boolean> though.
p = s -> true;
This takes a String (s) but because true is an expression and not a statement, the result cannot be ignored in the same way. The compiler has to add an implicit return because an expression can't exist on its own. Thus, this does have a return: a boolean. Therefore it's not a Consumer.**
p = s -> ("".equals(s));
Again, this is an expression, not a statement. Ignoring lambdas for a moment, you will see the line System.out.println("Hello"); will similarly fail to compile if you wrap it in parentheses.
*From the spec:
If the body of a lambda is a statement expression (that is, an expression that would be allowed to stand alone as a statement), it is compatible with a void-producing function type; any result is simply discarded.
**From the spec (thanks, Eugene):
A lambda expression is congruent with a [void-producing] function type if ...
the lambda body is either a statement expression
(§14.8)
or a void-compatible block.
I think the other answers complicate the explanation by focusing on lambdas whereas their behavior in this case is similar to the behavior of manually implemented methods. This compiles:
new Consumer<String>() {
#Override
public void accept(final String s) {
"".equals(s);
}
}
whereas this does not:
new Consumer<String>() {
#Override
public void accept(final String s) {
true;
}
}
because "".equals(s) is a statement but true is not. A lambda expression for a functional interface returning void requires a statement so it follows the same rules as a method's body.
Note that in general lambda bodies don't follow exactly the same rules as method bodies - in particular, if a lambda whose body is an expression implements a method returning a value, it has an implicit return. So for example, x -> true would be a valid implementation of Function<Object, Boolean>, whereas true; is not a valid method body. But in this particular case functional interfaces and method bodies coincide.
s -> "".equals(s)
and
s -> true
don't rely on same function descriptors.
s -> "".equals(s) may refer either String->void or String->boolean function descriptor.
s -> true refers to only String->boolean function descriptor.
Why ?
when you write s -> "".equals(s), the body of the lambda : "".equals(s) is a statement that produces a value.
The compiler considers that the function may return either void or boolean.
So writing :
Function<String, Boolean> function = s -> "".equals(s);
Consumer<String> consumer = s -> "".equals(s);
is valid.
When you assign the lambda body to a Consumer<String> declared variable, the descriptor String->void is used.
Of course, this code doesn't make much sense (you check the equality and you don't use the result) but the compiler doesn't care.
It is the same thing when you write a statement : myObject.getMyProperty() where getMyProperty() returns a boolean value but that you don't store the result of it.
when you write s -> true, the body of the lambda : true is a single expression .
The compiler considers that the function returns necessarily boolean.
So only the descriptor String->boolean may be used.
Now, come back to your code that doesn't compile.
What are you trying to do ?
Consumer<String> p = s -> true;
You cannot. You want to assign to a variable that uses the function descriptor Consumer<String> a lambda body with the String->void function descriptor.
It doesn't match !

How to suitably compose Predicate and Function in a Java function?

The purpose is to create a new Predicate usable in a stream filter :
myCollectionOfElement
.stream()
.filter(
MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1()))
.sorted(MyStaticHelperClass.getOtherSubElement().reversed())
.limit(10)
.collect(Collectors.toList())
getSubElement1OfTheElement() returns Function<E,S> (E contains a S property)
getPredicate1OnSubElement1() returns Predicate<S>
I use static functions to expose method references and functions.
I do this because the stream is called in a Velocity template and this context doesn't support lambda syntax and method reference.
I don't want to create a static function for all possible combinaisons, so I really want them to be composable.
For example here, I don't want to have a static getPredicate1OnElementThatCheckProperty1OnTheSubElement1() because I can compose getSubElement1OfTheElement() and getPredicate1OnSubElement1().
So I need a compose function :
// returns a new Predicate constructed by applying Predicate predicate on the result of Function function
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<S> predicate)
// most intuitive : lambda
return value -> predicate.test(function.apply(value));
// with method references
return function.andThen(predicate::test)::apply;
// predicate.compose is not available because Predicate interface doesn't extends Function interface
inspired by Is there a convenience method to create a Predicate that tests if a field equals a given value?
// step by step with variables
Function <S,Boolean> predicateFunction = predicate::test;
// a kind of #FunctionalInterface implicit "conversion" ? Predicate -> Function.
// is that safe ?
Function <E,Boolean> composed = function.andThen(predicateFunction::apply);
return composed::apply;
Edit :
It's called a cast context : https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
// the implementation of my compose can also be this ugly one-liner :
return ((Function <S,Boolean>)predicate::test).compose(function)::apply;
So, we cannot implement a generic compose function taking any functional interface (in my case Function and Predicate) because the name of the abstract method differs for each interface (test and apply in my case).
I'm OK with that.
To conclude, what I really need is two static functions, one that converts a Predicate to a Function and the opposite. Every Predicate will be used as a Function and the final operation will convert the composed Function to Predicate in order to match with the parameter type of the filter function.
public static <S> Function<S,Boolean> predicateToFunction(Predicate<S> predicate){
return predicate::test;
}
public static <S> Predicate<S> functionToPredicate(Function<S,Boolean> function){
return function::apply;
}
Is that correct ?
If so, is there any interest in releasing the bounds in the function signature ?
I answer my own questions.
Use lambda :
value -> predicate.test(function.apply(value));
Or if you really want/have to write a compose function, signature must be something like :
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<? super S> predicate)
I think the best approach would be use the boolean compose methods Predicate provides: and, or, not. e.g.,
private Predicate<String> startsWith(String prefix) {
return s -> s.startsWith(prefix);
}
private Predicate<String> endsWith(String suffix) {
return s -> s.endsWith(suffix);
}
Stream.of("Foo","Fuz","Doo","Fo")
.filter(startsWith("F").and(endsWith("o")))
.forEach(System.out::println);

Mockito returnsFirstArg() to use

I've started using the Mockito AdditionalAnswers#returnsFirstArg, which is great:
when(myMock.myFunction(anyString())).then(returnsFirstArg());
but I was wondering if there is an easy way to extract the input argument in order to be used for example in a constructor like:
when(myMock.myFunction(anyString())).thenReturn(new MyObject((String)returnsFirstArg()));
(which obviously doesn't work...)
The easiest (only?) approach, IMHO, would be to use the thenAnswer method, which allows you to not only return a value, but actually execute some code. Java 8 makes this particularly elegant, as you could just use an anonymous lambda:
when(myMock.myFunction(anyString()))
.thenAnswer(i -> new MyObject((String)i.getArguments()[0]);
I think you maybe need a helper class AnswerPipeline that I will introduce it a moment how to make the test more readable, more expressiveness and more interesting!!!
Note: you can transform any Answer to AnswerPipeline by AnswerPipeline#will(Answer) method, not only returnsFirstArg().
THEN using syntax sugar to describe the test, for example:
Function<String, String> function = mock(Function.class);
when(function.apply(anyString())).then(
/**/ will(returnsFirstArg()) // adapt an Answer to an AnswerPipeline
/**/.as(String.class) // set the result type
/**/.to(String::toUpperCase) // transforming the result
);
assertThat(function.apply("first"), equalTo("FIRST"));
AND then it is easy to solving your problem with no difficulty:
when(myMock.myFunction(anyString()))
.then(will(returnsFirstArg()).as(String.class).to(MyObject::new));
AnswerPipeline class
interface AnswerPipeline<T> extends Answer<T> {
static <R> AnswerPipeline<R> will(Answer<R> answer) {
return answer::answer;
}
default <R> AnswerPipeline<R> as(Class<R> type) {
return to(type::cast);
}
default <R> AnswerPipeline<R> to(Function<T, R> mapper) {
return it -> mapper.apply(answer(it));
}
}
You can use thenAnswer method and create an Answer to get the argument:
when(myMock.myFunction(anyString())).thenAnswer(new Answer<MyObject>() {
#Override
public MyObject answer(InvocationOnMock invocation) throws Throwable {
String s = invocation.getArgument(0); // get first argument
return new MyObject(s);
}
});
If you're using java 8, you can use lambda syntax:
when(myMock.myFunction(anyString()))
.thenAnswer(args -> new MyObject(args.getArgument(0)));
Notes:
I didn't need to cast invocation.getArgument(0) to String, but depending on your java/mockito version, maybe it'll be necessary: (String) invocation.getArgument(0)
depending on your mockito version, the getArgument(int) method might not exist and you should use getArgumentAt(int, Class) instead (in this case, the call would be getArgumentAt(0, String.class)). Or you can use getArguments()[0] and cast it to String

Categories