Helper methods for creating tuples and tupled functions in Java? - java

I'm using Java 8 along with the Pair from Apache Commons Lang3.
The first thing I am trying to do is get a stream from a List<T> and to take a Function<T,U> and ultimately create a List<Pair<T,U>>. Currently I am creating a Function<T,Pair<T,U>> with the specific types I want and using this to map the stream. What I want is something like:
public static <T, U> Function<T, Pair<T, U>> tupledResult(final Function<T, U> generator) {
Objects.requireNonNull(generator);
return (T t) -> new ImmutablePair<>(t, generator.apply(t));
}
The next problem is that now that I have a List<Pair<T, U>> I want to be able to use foreach to apply a BiConsumer<T,U> (similar to the tupled function in Scala). I guess it would look like:
public static <T, U> Consumer<Pair<T, U>> tupled(final BiConsumer<T, U> consumer) {
Objects.requireNonNull(consumer);
return (final Pair<T, U> p) -> consumer.accept(p.getLeft(), p.getRight());
}
Is there anything in Apache Commons Lang3 that does this or should I roll my own? If the later, is this something that is useful to contribute or is this a bad solution?
Example
This is the sort of thing I want to achieve:
private void doStuff(final List<Thing> things) {
final List<Pair<Thing, Other>> otherThings = things.stream()
.map(tupledResult(ThingHelper::generateOther))
.collect(Collectors.toList());
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomething(thing, other);
}));
otherThings.stream().forEach(tupled((final Thing thing, final Other other) -> {
doSomethingElse(thing, other);
}));
}
The points here are that ThingHelper.generateOther is relatively expensive and I only want to do it once. Also doSomething must be applied to everything first and then doSomethingElse afterwards.
The pairs never leave the scope of this method nor do I want to overload the methods to take a pair. In this case I really don't care about the lack of semantics of the pair, all that matters is the order. doSomething and doSomethingElse are the ones providing the semantics.

Such methods are absent in Apache Commons Lang3 as this library is Java 6 compatible, but the methods you want must return objects of java.util.function package which appeared only in Java 8.
If your Thing objects are not repeating, it's quite natural in your case to use Map instead:
private void doStuff(final List<Thing> things) {
final Map<Thing, Other> otherThings = things.stream()
.collect(Collectors.toMap(Function.identity(), ThingHelper::generateOther));
otherThings.forEach((final Thing thing, final Other other) -> {
doSomething(thing, other);
});
otherThings.forEach((final Thing thing, final Other other) -> {
doSomethingElse(thing, other);
});
}
Or even shorter:
private void doStuff(List<Thing> things) {
Map<Thing, Other> otherThings = things.stream()
.collect(toMap(x -> x, ThingHelper::generateOther));
otherThings.forEach(this::doSomething);
otherThings.forEach(this::doSomethingElse);
}
This way you don't need wrappers as Map.forEach already accepts BiConsumer and Collectors.toMap second parameter essentially replaces your tupledResult.

In FunctionalJava (https://github.com/functionaljava/functionaljava) I would do:
private void doStuff(final List<Thing> things) {
fj.data.List<P2<Thing, Other>> otherThings = fj.data.List.list(things)
.map(t -> P.p(t, ThingHelper.generateOther.apply(t)));
otherThings.forEachDoEffect(p -> doSomething(p._1(), p._2()));
otherThings.forEachDoEffect(p -> doSomethingElse(p._1(), p._2()));
}
Tuples are supported as products with classes P, P1, P2, etc (https://functionaljava.ci.cloudbees.com/job/master/javadoc/).

Related

How to bind a Java Supplier to an instance of an object?

How can I bind a Java Supplier to an existing instance of an Object? For example, if I want to write my own compareTo() method with this header:
public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
I want be able to call it like:
myCompareTo("Hello", "Hello2", String::length);
where String (with the capital letter) is a class and no object. So how can I bind the instance o1 to the supplier?
Here's what you were searching for (I believe):
public static <T, U extends Comparable<U>> int compare(T o1, T o2, Function<T, U> mapper) {
return mapper.apply(o1).compareTo(mapper.apply(o2));
}
You can call that like so:
compare("str1", "str2", String::length); // 0
Thanks for your answers. Actually I figured it out now. I wanted to have the supplied object instances (o1 and o2) to execute the given method. I found out that Supplier was the wrong interface instead I had to use Function. Here you can see my working simplified example:
public static <T> int myCompareTo(T o1, T o2, Function<T, Comparable> getter) {
return getter.apply(o1).compareTo(getter.apply(o2));
}
The reason, the interface has to be Function and not Supplier is, that only Function is equivalent to a lambda expression taking an object and calls the referenced method on the object.
For example, if you define the method reference as:
Function<TypeOfInstance, ReturnTypeOfReferencedMethod> methodReference = TypeOfInstance::referencedMethod();
then the equivalent lambda expression being executed is:
(instance) -> instance.referencedMethod()
Additional Information:
Edit: I know I could have done the same by using Comparator, but this example is very simplified. In my application a Function of this kind is neccessary. I had to create a compareTo function that sorts an ArrayList by more than one attribute because the main sorting attribute may not be unique in the list. I want to share my code with you, because I think it can be a interesting insight for you.
public static <T> int ultimateCompare(T o1, T o2, Function<T, Comparable>... getters) {
for (Function<T, Comparable> getter : getters) {
int result = getter.apply(o1).compareTo(getter.apply(o2));
if (result != 0) return result;
}
return 0;
}
With this for example, you can sort a list of persons by last name and if two of them are identical, you can use the first name to sort. With this solution you can change sorting at runtime.
Actually a more correct way to define your method would be:
private static <T, U extends Comparable<? super U>> int myCompareTo(T left, T right, Function<T, U> fu) {
return Comparator.comparing(fu).compare(left, right);
}
You can use
Comparator.comparing(String::length);
to obtain a comparator instance which you can pass to the method.

Java Lambda to comparator conversion - intermediate representation

I'm trying to make sense of how Comparator.comparing function works. I created my own comparing method to understand it.
private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
return (Comparator<T>) bfun;
}
The last line in this function throws an exception.
However, if I change this function to
private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
return (T a, T b) -> f.apply(a).compareTo(f.apply(b));
}
It works just fine as expected.
What is the intermediate functional interface which the second attempt uses, which is able to convert the lambda to Comparator?
What is the intermediate functional interface which the second attempt uses, which is able to convert the lambda to Comparator?
The Comparator itself.
Within the second method, you have defined a Comparator, not an intermediate object that has been cast to the Comparator.
The last line in this function throws an exception.
Yes, it should.
If two classes are functional interfaces and have similar methods (with the identical signatures and the same return type), it doesn't mean that they can be used interchangeably.
An interesting trick - you may make a Comparator<T> by referring to the BiFunction<T, T, Integer> bfun's method apply:
private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
final BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
return bfun::apply; // (a, b) -> bfun.apply(a, b);
}
The intermediate functional interface in your second attempt is simply Comparator<T>:
You can see this because your code-snippet is equivalent to the following:
private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) {
Comparator<T> comparator = (T a, T b) -> f.apply(a).compareTo(f.apply(b));
return comparator;
}

Java 8 Streams: simplifying o1 -> Objects.equals(o1.getSome().getSomeOther(), o2.getSome().getSomeOther()) in a stream

Given the following code:
stream.filter(o1 -> Objects.equals(o1.getSome().getSomeOther(),
o2.getSome().getSomeOther())
How could that possibly be simplified?
Is there some equals-utility that lets you first extract a key just like there is Comparator.comparing which accepts a key extractor function?
Note that the code itself (getSome().getSomeOther()) is actually generated from a schema.
EDIT: (after discussing with a collegue and after revisiting: Is there a convenience method to create a Predicate that tests if a field equals a given value?)
We now have come to the following reusable functional interface:
#FunctionalInterface
public interface Property<T, P> {
P extract(T object);
default Predicate<T> like(T example) {
Predicate<P> equality = Predicate.isEqual(extract(example));
return (value) -> equality.test(extract(value));
}
}
and the following static convenience method:
static <T, P> Property<T, P> property(Property<T, P> property) {
return property;
}
The filtering now looks like:
stream.filter(property(t -> t.getSome().getSomeOther()).like(o2))
What I like on this solution in respect to the solution before: it clearly separates the extraction of the property and the creation of the Predicate itself and it states more clearly what is going on.
Previous solution:
<T, U> Predicate<T> isEqual(T other, Function<T, U> keyExtractFunction) {
U otherKey = keyExtractFunction.apply(other);
return t -> Objects.equals(keyExtractFunction.apply(t), otherKey);
}
which results in the following usage:
stream.filter(isEqual(o2, t -> t.getSome().getSomeOther())
but I am more then happy if anyone has a better solution.
I think that your question's approach is more readable than your answer's one. And I also think that using inline lambdas is fine, as long as the lambda is simple and short.
However, for maintainance, readability, debugging and testability reasons, I always move the logic I'd use in a lambda (either a predicate or function) to one or more methods. In your case, I would do:
class YourObject {
private Some some;
public boolean matchesSomeOther(YourObject o2) {
return this.getSome().matchesSomeOther(o2.getSome());
}
}
class Some {
private SomeOther someOther;
public boolean matchesSomeOther(Some some2) {
return Objects.isEqual(this.getSomeOther(), some2.getSomeOther());
}
}
With these methods in place, your predicate now becomes trivial:
YourClass o2 = ...;
stream.filter(o2::matchesSomeOther)

Java - Is there a "convertible" interface?

Is there an existing interface (or abstract class) that allows you to define conversions between two different types?
You would implement (or extend) it, and for example, you can convert between a Foo and a Bar.
Example Interface:
public interface ConvertibleInterface<T, U> {
public U to(T item);
public T from(U item);
}
I was just wondering if something like this exists in the java system libraries.
You could use the new Function<T, U> type to define something that would convert to and from the given type:
Function<String, Integer> toInt = (String in) -> Integer.parseInt(in);
Function<Integer, String> toString = (Integer in) -> in.toString();
Integer converted = toInt.apply("101");
See the API docs here. This has been added in Java 8, so make sure you are up to date.

How to negate a method reference predicate

In Java 8, you can use a method reference to filter a stream, for example:
Stream<String> s = ...;
long emptyStrings = s.filter(String::isEmpty).count();
Is there a way to create a method reference that is the negation of an existing one, i.e. something like:
long nonEmptyStrings = s.filter(not(String::isEmpty)).count();
I could create the not method like below but I was wondering if the JDK offered something similar.
static <T> Predicate<T> not(Predicate<T> p) { return o -> !p.test(o); }
Predicate.not( … )
java-11 offers a new method Predicate#not
So you can negate the method reference:
Stream<String> s = ...;
long nonEmptyStrings = s.filter(Predicate.not(String::isEmpty)).count();
I'm planning to static import the following to allow for the method reference to be used inline:
public static <T> Predicate<T> not(Predicate<T> t) {
return t.negate();
}
e.g.
Stream<String> s = ...;
long nonEmptyStrings = s.filter(not(String::isEmpty)).count();
Update: Starting from Java-11, the JDK offers a similar solution built-in as well.
There is a way to compose a method reference that is the opposite of a current method reference. See #vlasec's answer below that shows how by explicitly casting the method reference to a Predicate and then converting it using the negate function. That is one way among a few other not too troublesome ways to do it.
The opposite of this:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
is this:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
or this:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
Personally, I prefer the later technique because I find it clearer to read it -> !it.isEmpty() than a long verbose explicit cast and then negate.
One could also make a predicate and reuse it:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
Or, if having a collection or array, just use a for-loop which is simple, has less overhead, and *might be **faster:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
*If you want to know what is faster, then use JMH http://openjdk.java.net/projects/code-tools/jmh, and avoid hand benchmark code unless it avoids all JVM optimizations — see Java 8: performance of Streams vs Collections
**I am getting flak for suggesting that the for-loop technique is faster. It eliminates a stream creation, it eliminates using another method call (negative function for predicate), and it eliminates a temporary accumulator list/counter. So a few things that are saved by the last construct that might make it faster.
I do think it is simpler and nicer though, even if not faster. If the job calls for a hammer and a nail, don't bring in a chainsaw and glue! I know some of you take issue with that.
wish-list: I would like to see Java Stream functions evolve a bit now that Java users are more familiar with them. For example, the 'count' method in Stream could accept a Predicate so that this can be done directly like this:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());
Predicate has methods and, or and negate.
However, String::isEmpty is not a Predicate, it's just a String -> Boolean lambda and it could still become anything, e.g. Function<String, Boolean>. Type inference is what needs to happen first. The filter method infers type implicitly. But if you negate it before passing it as an argument, it no longer happens. As #axtavt mentioned, explicit inference can be used as an ugly way:
s.filter(((Predicate<String>) String::isEmpty).negate()).count()
There are other ways advised in other answers, with static not method and lambda most likely being the best ideas. This concludes the tl;dr section.
However, if you want some deeper understanding of lambda type inference, I'd like to explain it a bit more to depth, using examples. Look at these and try to figure out what happens:
Object obj1 = String::isEmpty;
Predicate<String> p1 = s -> s.isEmpty();
Function<String, Boolean> f1 = String::isEmpty;
Object obj2 = p1;
Function<String, Boolean> f2 = (Function<String, Boolean>) obj2;
Function<String, Boolean> f3 = p1::test;
Predicate<Integer> p2 = s -> s.isEmpty();
Predicate<Integer> p3 = String::isEmpty;
obj1 doesn't compile - lambdas need to infer a functional interface (= with one abstract method)
p1 and f1 work just fine, each inferring a different type
obj2 casts a Predicate to Object - silly but valid
f2 fails at runtime - you cannot cast Predicate to Function, it's no longer about inference
f3 works - you call the predicate's method test that is defined by its lambda
p2 doesn't compile - Integer doesn't have isEmpty method
p3 doesn't compile either - there is no String::isEmpty static method with Integer argument
Building on other's answers and personal experience:
Predicate<String> blank = String::isEmpty;
content.stream()
.filter(blank.negate())
Another option is to utilize lambda casting in non-ambiguous contexts into one class:
public static class Lambdas {
public static <T> Predicate<T> as(Predicate<T> predicate){
return predicate;
}
public static <T> Consumer<T> as(Consumer<T> consumer){
return consumer;
}
public static <T> Supplier<T> as(Supplier<T> supplier){
return supplier;
}
public static <T, R> Function<T, R> as(Function<T, R> function){
return function;
}
}
... and then static import the utility class:
stream.filter(as(String::isEmpty).negate())
Shouldn't Predicate#negate be what you are looking for?
In this case u could use the org.apache.commons.lang3.StringUtilsand do
int nonEmptyStrings = s.filter(StringUtils::isNotEmpty).count();
I have written a complete utility class (inspired by Askar's proposal) that can take Java 8 lambda expression and turn them (if applicable) into any typed standard Java 8 lambda defined in the package java.util.function. You can for example do:
asPredicate(String::isEmpty).negate()
asBiPredicate(String::equals).negate()
Because there would be numerous ambiguities if all the static methods would be named just as(), I opted to call the method "as" followed by the returned type. This gives us full control of the lambda interpretation. Below is the first part of the (somewhat large) utility class revealing the pattern used.
Have a look at the complete class here (at gist).
public class FunctionCastUtil {
public static <T, U> BiConsumer<T, U> asBiConsumer(BiConsumer<T, U> biConsumer) {
return biConsumer;
}
public static <T, U, R> BiFunction<T, U, R> asBiFunction(BiFunction<T, U, R> biFunction) {
return biFunction;
}
public static <T> BinaryOperator<T> asBinaryOperator(BinaryOperator<T> binaryOperator) {
return binaryOperator;
}
... and so on...
}
You can use Predicates from Eclipse Collections
MutableList<String> strings = Lists.mutable.empty();
int nonEmptyStrings = strings.count(Predicates.not(String::isEmpty));
If you can't change the strings from List:
List<String> strings = new ArrayList<>();
int nonEmptyStrings = ListAdapter.adapt(strings).count(Predicates.not(String::isEmpty));
If you only need a negation of String.isEmpty() you can also use StringPredicates.notEmpty().
Note: I am a contributor to Eclipse Collections.
You can accomplish this as long emptyStrings = s.filter(s->!s.isEmpty()).count();
Tip: to negate a collection.stream().anyMatch(...), one can use collection.stream().noneMatch(...)
If you're using Spring Boot (2.0.0+) you can use:
import org.springframework.util.StringUtils;
...
.filter(StringUtils::hasLength)
...
Which does:
return (str != null && !str.isEmpty());
So it will have the required negation effect for isEmpty

Categories