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)));
}
Related
I want to filter a collection of values in Kotlin using an instance of a java.util.Predicate implementation, basically something like this:
val predicate = JsQueryPredicate<SportEvent>(query)
schedule.sport_events.filter(predicate)
This doesn't compile though. The following works, is that the recommended way of doing this? Feels a bit cumbersome
val predicate = JsQueryPredicate<SportEvent>(query)
schedule.sport_events.filter { predicate.test(it) }
You can use a method reference, which gets converted implicitly to a (T) -> Boolean and thus allows you to call the filter method:
schedule.sport_events.filter(predicate::test)
To answer it more directly: yes... predicate.test(it) or the nearly equivalent method reference predicate::test are the way to go... except...
If you have to deal with Java predicates more often and/or the refactoring of the Java functional types (e.g. Predicate) to Kotlin function types is planned in future, you may also want to add appropriate extension functions instead, e.g.:
fun <T> Iterable<T>.filter(predicate: Predicate<T>) = filter { predicate.test(it) }
With the following usage then:
val javaPredicate : Predicate<String> = Predicate { it == "hello" }
listOf("hello", "world")
.filter(javaPredicate)
If you replaced the Predicate in future to, e.g. (T) -> Boolean you then don't need to adapt that filter, but just replace/remove the import statement to the extension function.
Extension functions to just transform the Predicate to an appropriate Kotlin function type are possible too, but may not help you that much in future refactorings:
operator fun <T> Predicate<T>.invoke() : (T) -> Boolean = ::test
fun <T> Predicate<T>.transform() : (T) -> Boolean = ::test
Usage samples of those:
val javaPredicate : Predicate<String> = Predicate { it == "hello" }
// variant with Predicate.invoke:
listOf("hello", "world")
.filter(javaPredicate())
// variant using Predicate.transform()
listOf("hello", "world")
.filter(javaPredicate.transform())
So I recommend you the overloaded filter-method in case you plan a refactoring or otherwise just stick to filter { predicate.test(it) }/filter(predicate::test), which might make a future refactoring a bit (IDEs help ;-)) harder.
I'm learning about lambda expressions.
Given a list of names, I want to count the numbers of names that start with N.
I did that:
final static List<String> friends = Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");
public static int countFriendsStartWithN() {
return Math.toIntExact(friends
.stream()
.filter(name -> name.startsWith("N"))
.count());
}
The call to the count method returns a primitive long but I want an int.
I used Math.toIntExact to get the long value as int.
Is it possible to get the int value directly inside the lambda expression?
No, it is not possible to fit your call to toIntExact into your chain of method calls, your stream pipeline. This is because count is a terminal operation and returns a primitive long on which no method call is possible. A terminal operation is an operation that ends the stream pipeline and produces a result (or a side effect).
So I believe the best thing you can do is to live with the code you already have. IMHO it’s fine.
Well, here's a somewhat silly way of calculating the count as an int without casting:
public static int countFriendsStartWithN() {
return friends.stream()
.filter(name -> name.startsWith("N"))
.mapToInt (s -> 1)
.sum();
}
You can't do anything inside the lambda expression you currently have, since that's a Predicate: it returns a boolean. Math.toIntExact returns an int.
You can do it without the Math.toIntExact (or a simple cast) like so:
return /* create stream, filter */
.mapToInt(a -> 1).sum();
But this is likely to be slower than doing what you are doing at the moment.
Yet another option that is not really better - it is possible to use a collector that applies a finisher:
public static int countFriendsStartWithN() {
return friends.stream()
.filter(name -> name.startsWith("N"))
.collect(Collectors.collectingAndThen(Collectors.counting(), Math::toIntExact));
}
This may have an advantage if you need it frequenty - you could build a utility method returning this Collector to make it reusable.
Here's a way to do this with reduce
public static int countFriendsStartWithN2() {
return friends
.stream()
.filter(name -> name.startsWith("N"))
.map(s -> 1)
.reduce(0, Integer::sum);
}
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);
I have an Optional that I want to "convert" to an OptionalInt, but there doesn't seem to be a simple way to do this.
Here's what I want to do (contrived example):
public OptionalInt getInt() {
return Optional.ofNullable(someString).filter(s -> s.matches("\\d+")).mapToInt(Integer::parseInt);
}
However, there's no mapToInt() method for Optional.
The best I could come up with is:
return Optional.ofNullable(someString)
.filter(s -> s.matches("\\d+"))
.map(s -> OptionalInt.of(Integer.parseInt(s)))
.orElse(OptionalInt.empty());
but that seems inelegant.
Am I missing something from the JDK that can make the conversion more elegant?
While the code isn't more readable than an ordinary conditional expression, there is a simple solution:
public OptionalInt getInt() {
return Stream.of(someString).filter(s -> s != null && s.matches("\\d+"))
.mapToInt(Integer::parseInt).findAny();
}
With Java 9, you could use
public OptionalInt getInt() {
return Stream.ofNullable(someString).filter(s -> s.matches("\\d+"))
.mapToInt(Integer::parseInt).findAny();
}
As said, neither is more readable than an ordinary conditional expression, but I think, it still looks better than using mapOrElseGet (and the first variant doesn't need Java 9.
No, there's no way to do it in more elegant way using standard Java API. I asked Paul Sandoz about adding mapToInt, etc., here's his answer:
Me:
Isn't it a good idea to provide also a way
to transfer between Optional types like mapToInt, mapToObj, etc.,
like it's done in Stream API?
Paul:
I don’t wanna go there, my response is transform Optional* into a *Stream. An argument for adding mapOrElseGet (notice that the primitive variants return U) is that other functionality can be composed from it.
So you will likely to have in Java-9:
return Optional.of(someString).filter(s -> s.matches("\\d+"))
.mapOrElseGet(s -> OptionalInt.of(Integer.parseInt(s)), OptionalInt::empty);
But nothing more.
That's because JDK authors insist that the Optional class and its primitive friends (especially primitive friends) should not be widely used, it's just a convenient way to perform a limited set of operations on the return value of methods which may return "the absence of the value". Also primitive optionals are designed for performance improvement, but actually it's much less significant than with streams, so using Optional<Integer> is also fine. With Valhalla project you will be able to use Optional<int> and OptionalInt will become unnecessary.
In your particular case the better way to do it is using ternary operator:
return someString != null && someString.matches("\\d+") ?
OptionalInt.of(Integer.parseInt(someString)) : OptionalInt.empty();
I assume that you want to return the OptionalInt from the method. Otherwise it's even more questionable why you would need it.
If you have any object and not just a String, you can temporarily go through a Stream:
public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) {
return optional.map(Stream::of).orElseGet(Stream::empty)
.mapToInt(func)
.findFirst();
}
This solution has the advantage to be a one-liner, meaning you can copy/paste the content of the method and just change func to whatever you want. The disadvantage is going through a Stream to achieve what you want. But if you want a generic one-liner, this is it.
If you want a utility method, you probably prefer to use the following:
public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) {
if (optional.isPresent()) {
return OptionalInt.of(func.applyAsInt(optional.get()));
} else {
return OptionalInt.empty();
}
}
This is how I convert an Optional<String> to OptionalInt
OptionalInt lastSeenId = Optional.of("123").map(Integer::parseInt).map(OptionalInt::of).orElseGet(OptionalInt::empty);
Here's another option that doesn't need to use a Stream and avoids compiling regex every time:
private static final Predicate<String> IS_DIGITS = Pattern.compile("^\\d+$")
.asPredicate();
public OptionalInt getInt() {
return Optional.ofNullable(someString)
.filter(IS_DIGITS)
.map(Integer::valueOf)
.map(OptionalInt::of)
.orElseGet(OptionalInt::empty);
}
Note that you need to anchor the regex because asPredicate() uses find() instead of matches().
Or if you're using Guava, you can eliminate the regex entirely and use their Ints class:
public OptionalInt getInt() {
return Optional.ofNullable(someString)
.map(Ints::tryParse)
.map(OptionalInt::of)
.orElseGet(OptionalInt::empty);
}
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.