Implementing functional fold_right in Java - java

I'm trying to implement the functional method fold_right using some of Java's functional features. The code I have below works, but I don't really understand why it works - I think the main problem is that I'm a little bit uncertain about how lambdas work in Java (especially when using them with generics). For instance, why do I have to call the lambda I return in apply() by calling apply again? The class I'm taking is taught in OCaml, and it's easy for me to understand the fold_right function that OCaml has in its standard library. The way I implemented it in Java just seems so much more clunky and verbose - could someone maybe shed some light on this for me?
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
interface Func<A,B> {
B apply(A a);
}
class Add implements Func<Integer, Func<Integer,Integer>> {
#Override
public Func<Integer,Integer> apply(Integer a) {
return (b) -> a + b;
}
}
public class Fold {
public static <E> E fold(Func<E,Func<E,E>> f, E acc, LinkedList<E> lst) {
if (lst.isEmpty()) {
return acc;
} else {
LinkedList<E> listClone = (LinkedList<E>) lst.clone();
E theHead = listClone.removeFirst();
return (E) f.apply(theHead).apply((fold(f,acc,listClone)));
}
}
public static void main(String[] args) {
Integer[] nums = {1,2,3,4,5};
List<Integer> nums_lst = Arrays.asList(nums);
LinkedList<Integer> lst = new LinkedList<Integer>(nums_lst);
int result = Fold.fold(new Add(), 0, lst);
System.out.println(result); // should be 15
System.out.println(lst); // should be [1,2,3,4,5]
}
}

Slightly off topic, but java has a built in Function<T, R>, that being said, to understand how the code works, let's start with the Func<A, B> interface:
interface Func<A,B> {
B apply(A a);
}
So at a first glance, we have two types namely A, B and the apply method tells me that it takes in an argument of type A and returns an object of type B. Ok moving on to the Add class, this class implements the Func interface as:
Func<Integer, Func<Integer, Integer>>
So based on our previous reasoning, the apply method implemented in Add will take in an Integer and return a Func<Integer, Integer>. So when wee look at the fold method in side the Fold class: (you can think of E as Object for simplicity)
public static <E> E fold(Func<E,Func<E,E>> f, E acc, LinkedList<E> lst) {
if (lst.isEmpty()) {
return acc;
} else {
LinkedList<E> listClone = (LinkedList<E>) lst.clone();
E theHead = listClone.removeFirst();
// A B <- remember the Func interface? here A is E and B is Func<E,E>
// f is a Func<E, Func<E, E>> that takes in an E and returns
// another Func<E, E> after calling apply thus
// breaking the steps:
// f.apply(E) <- we just called the apply method thus this should return a "B"
// Since B is a Func<E, E> we need to call apply to perform the operation
// onto the next element, which in this case is an addition. You can think
// of it as a -> b -> a + b.
// Now you played that nice trick of using recursion to call this function
// and traverse all elements till the end of the collection and accumulate
// all the intermediate results.
return (E) f.apply(theHead).apply((fold(f,acc,listClone)));
// the listClone is one element shorter in each recursion
// since you are removing the first element
}
}
On a side note, since your Func<A, B>, matches the signature of the java.util.Function you can pass the Add as a lambda without implementing the Add class explicilty:
public static void main(String[] args) {
Integer[] nums = {1,2,3,4,5};
List<Integer> nums_lst = Arrays.asList(nums);
LinkedList<Integer> lst = new LinkedList<Integer>(nums_lst);
int result = Fold.fold(a -> b -> a + b, 0, lst);
System.out.println(result); // should be 15
System.out.println(lst); // should be [1,2,3,4,5]
}

Related

Can I write a for loop that iterates over both collections and arrays?

Is there a possibility to check if an object is either an array or a collection with one clause? What I am trying to achieve:
Assuming arrays implement Iterable, and assuming the Object foo could be either an array or a collection, I'd like to use a code snippet like this:
if (foo instanceof Iterable) {
for (Object f : (Iterable) foo) {
// do something with f
}
}
Unfortunately, an array cannot be cast to Iterable. Nor does it implement Collection. Are there any other possibilities to handle both in one loop like the above? Instead of -- of course -- using an if-else if-clause and two loops (which wouldn't be nice).
Edit: In response to these answers. I am aware of the isArray() method but in this case the casting in
...
for (Object f : (Iterable) foo) {
...
will fail. That'd a pity and a code redundancy since I would have to use two loops although a foreach-loop works both with Collections and Arrays.
Regarding a condition to check if foo is either a collection or an array:
Class#isAssignableFrom may come in handy.
Class<?> fooClass = foo.getClass();
boolean isArrayOrCollection = Collection.class.isAssignableFrom(fooClass) ||
Object[].class.isAssignableFrom(fooClass);
I reasonably assume you won't test it on primitive arrays since you have collections which work only with the wrapper classes.
I guess you can safely replace Object[].class.isAssignableFrom(fooClass) with fooClass.isArray()
boolean isArrayOrCollection = Collection.class.isAssignableFrom(fooClass) ||
fooClass.isArray();
and it would also work for a primitive array class.
I've run a small "test"
class Test {
public static void main(String[] args) {
Predicate<Class<?>> p = c -> Collection.class.isAssignableFrom(c) ||
c.isArray();
System.out.println(p.test(new int[0].getClass()));
System.out.println(p.test(new Integer[0].getClass()));
System.out.println(p.test(Collections.emptyList().getClass()));
System.out.println(p.test(Collections.emptySet().getClass()));
System.out.println(p.test(Collections.emptyMap().getClass()));
}
}
which results in
true
true
true
true
false
Regarding a generic loop that would run over both arrays and
collections:
You simply can't write an accurate construction to handle this: Collection (or Iterable) and Object[] have little in common (Object as a common parent and its methods are not enough).
I think it's sensible to build own abstraction which would treat collections and arrays in the same manner. Having no particular context, I can come up with a simple idea of two subclasses, each of which defining how its source (either a collection or an array) should be iterated. Then, programming to an interface will help to manage them equally.
A very simplified example would be:
interface Abstraction<T> {
void iterate(Consumer<? super T> action);
static <T> Abstraction<T> of(Collection<T> collection) {
return new CollectionAbstraction<>(collection);
}
static <T> Abstraction<T> of(T[] array) {
return new ArrayAbstraction<>(array);
}
static IntArrayAbstraction of(int[] array) {
return new IntArrayAbstraction(array);
}
}
class CollectionAbstraction<T> implements Abstraction<T> {
Collection<T> source;
public CollectionAbstraction(Collection<T> source) {
this.source = source;
}
#Override
public void iterate(Consumer<? super T> action) {
source.forEach(action);
}
}
class ArrayAbstraction<T> implements Abstraction<T> {
T[] source;
public ArrayAbstraction(T[] source) {
this.source = source;
}
#Override
public void iterate(Consumer<? super T> action) {
for (T t : source) {
action.accept(t);
}
}
}
class IntArrayAbstraction implements Abstraction<Integer> {
int[] source;
public IntArrayAbstraction(int[] source) {
this.source = source;
}
#Override
public void iterate(Consumer<? super Integer> action) {
for (int t : source) {
action.accept(t);
}
}
}
class Test {
public static void main(String[] args) {
Abstraction.of(new Integer[] {1, 2, 3}).iterate(System.out::println);
Abstraction.of(Arrays.asList(1, 2, 3)).iterate(System.out::println);
Abstraction.of(new int[] {1, 2, 3}).iterate(System.out::println);
}
}
I believe the approach above is pretty versatile. You don't depend on how a certain source is iterated, you may selectively modify them.
The other answers are all trying hard to answer the original title question:
Is there a common interface or superclass for arrays and collections?
But your real question is in the body:
Are there any other possibilities to handle both in one loop like the above?
The answer is: No, there's no way to write a single for loop that iterates over both collections and arrays.
You could jump through a bunch of hoops to turn the arrays into lists, but you'll almost certainly end up with a bigger mess than if you just wrote two (or more) loops. Calling getClass().isArray() tells you what you have but you still can't work with it without some sort of cast. Arrays.asList() doesn't work for arrays of primitives.
Depending on what you are trying to do, you might want to implement two similar methods:
public <T> void iterateOver(List<T> list) {
// do whatever you want to do with your list
}
public <T> void iterateOver(T[] array) {
this.iterateOver(Arrays.asList(array));
}
Or maybe even have an interface for this:
interface ExtendedIterableConsumer<T> {
public void iterateOver(List<T> list);
public default void iterateOver(T[] array) {
this.iterateOver(Arrays.asList(array));
}
I am not sure if that helps you, because you seem to already have the object in question in a variable somewhere. But if you can address that problem one level higher, it might be useful.
You can check if object is array by using isArray() method from Class
if (foo != null && (foo.getClass().isArray() || foo instanceof Collection<?>)){
}
Edit:
In terms of iterating over this foo object, there is no simple solution. However you could try something like this:
private void iterate(#NotNull Object foo) {
if (foo instanceof Collection<?>) {
for (Object o : ((Collection<?>) foo)) {
chandleYourObject(o);
}
}
if (foo.getClass().isArray()) {
if (foo.getClass().isPrimitive()) {
checkPrimitiveTypes(foo);
}
if (foo instanceof Object[]) {
for (Object o : (Object[]) foo) {
chandleYourObject(o);
}
}
}
}
private void checkPrimitiveTypes(Object foo) {
if (foo instanceof int[]) {
for (int i : (int[]) foo) {
}
}
//And the rest of primitive types
}
private void chandleYourObject(Object o ){
//What you want to do with your object
}
You could write a helper method for this:
#SuppressWarnings("unchecked")
public static <E> void forEach(Object arrayOrIterable, Consumer<? super E> action) {
Objects.requireNonNull(arrayOrIterable);
if (arrayOrIterable instanceof Iterable) {
for (Object o : (Iterable<?>) arrayOrIterable) {
action.accept((E) o);
}
} else if (arrayOrIterable.getClass().isArray()) {
int length = Array.getLength(arrayOrIterable);
for (int i = 0; i < length; i++) {
action.accept((E) Array.get(arrayOrIterable, i));
}
} else {
throw new IllegalArgumentException("not an array nor iterable: " + arrayOrIterable.getClass());
}
}
The second branch makes use of the java.reflect.Array class which provides helper methods (may be slow), to get the length of an array and the element at a given index.
You may call it like this:
int[] ints = {1, 2, 3, 4};
forEach(ints, (Integer i) -> System.out.println(i));
List<Integer> ints = Arrays.asList(1, 2, 3, 4);
forEach(ints, (Integer i) -> System.out.println(i));
Due to the nature of generics, this method may throw a ClassCastException, e.g. this call:
int[] ints = {1, 2, 3, 4};
forEach(ints, (String s) -> System.out.println(s));
Would result in:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Arrays are Objects:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html
AbstractCollections also extend Object:
https://docs.oracle.com/javase/8/docs/api/java/util/AbstractCollection.html
So yes there is a common superclass, but unfortunately this isn't really going to help you.
I would suggest your best bet is to use:
List<> someList = Arrays.asList(sourceArray)
This will convert your array into a collection that implements Iterable. You will of course need to work out if the initial object is an Array or a Collection in advance and only call the above if it is an array, here are some options for doing that:
boolean isArray = myArray.getClass().isArray();
boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());

Generic Method That takes unique parameter and returns unique parameters Java

I have a requirement where in the function takes different parameters and returns unique objects. All these functions perform the same operation.
ie.
public returnObject1 myfunction( paramObject1 a, int a) {
returnObject1 = new returnObject1();
returnObject1.a = paramObject1.a;
return returnObject1;
}
public returnOject2 myfunction( paramObject2 a, int a){
returnObject2 = new returnObject2();
returnObject2.a = paramObject2.a;
return returnObject2;
}
As you can see above, both the function do the same task but they take different parameters as input and return different objects.
I would like to minimize writing different functions that does the same task.
Is it possible to write a generic method for this that can substitute the parameters based on the call to the function?
paramObject and returnObject are basically two classes that have different variables. They are not related to each other.
My objective is that I do not want to do function overloading since the functions do almost the same work. I would like to have a single function that can handle different input and different return output.
my aim is to do something like this (if possible):
public static < E > myfunction( T a, int a ) {
// do work
}
The return type E and the input T can keep varying.
you can using the 3rd apply method to remove the code duplications, you separate creation & initialization from the apply method in this approach. and don't care about which type of T is used. for example:
returnObject1 myfunction(paramObject1 a, int b) {
return apply(returnObject1::new, b, value -> {
//uses paramObject1
//populates returnObject1
//for example:
value.foo = a.bar;
});
}
returnOject2 myfunction(paramObject2 a, int b) {
return apply(returnOject2::new, b, value -> {
//uses paramObject2
//populates returnObject2
//for example:
value.key = a.value;
});
}
<T> T apply(Supplier<T> factory, int b, Consumer<T> initializer) {
T value = factory.get();
initializer.accept(value);
//does work ...
return value;
}
Note the 2 myfunction is optional, you can remove them from you source code, and call the apply method directly, for example:
paramObject2 a = ...;
returnObject2 result = apply(returnOject2::new, 2, value -> {
//for example:
value.key = a.value;
});
Make interface Foo and implement this interface in both paramObject1 and paramObject2 class. Now your method should be look like:
public Foo myFunction(Foo foo, int a){
//Rest of the code.
return foo;
}

Implement recursive lambda function using Java 8

Java 8 introduced lambda functions and I want to implement something like factorial:
IntToDoubleFunction fact = x -> x == 0 ? 1 : x * fact.applyAsDouble(x-1);
Compilation returns
error: variable fact might not have been initialized
How can I reference function itself. Class is anonymous but instance exists: It is called fact.
I usually use (once-for-all-functional-interfaces defined) generic helper class which wraps the variable of the functional interface type.
This approach solves the problem with the local variable initialization and allows the code to look more clearly.
In case of this question the code will look as follows:
// Recursive.java
// #param <I> - Functional Interface Type
public class Recursive<I> {
public I func;
}
// Test.java
public double factorial(int n) {
Recursive<IntToDoubleFunction> recursive = new Recursive<>();
recursive.func = x -> (x == 0) ? 1 : x * recursive.func.applyAsDouble(x - 1);
return recursive.func.applyAsDouble(n);
}
One way is to write a secondary function, helper, which takes a function and a number as arguments, and then write the function you actually want, fact = helper(helper,x).
Like so:
BiFunction<BiFunction, Double, Double> factHelper =
(f, x) -> (x == 0) ? 1.0 : x*(double)f.apply(f,x-1);
Function<Double, Double> fact =
x -> factHelper.apply(factHelper, x);
This seems to me to be slightly more elegant than relying on corner case semantics like a closure that captures a reference to a mutable structure, or allowing self-reference with a warning of the possibility of "might not be initialized."
Still, it's not a perfect solution because of Java's type system -- the generics cannot guarantee that f, the argument to factHelper, is of the same type as factHelper (i.e. same input types and output types), since that would be an infinitely nested generic.
Thus, instead, a safer solution might be:
Function<Double, Double> fact = x -> {
BiFunction<BiFunction, Double, Double> factHelper =
(f, d) -> (d == 0) ? 1.0 : d*(double)f.apply(f,d-1);
return factHelper.apply(factHelper, x);
};
The code smell incurred from factHelper's less-than-perfect generic type is now contained (or, dare I say, encapsulated) within the lambda, ensuring that factHelper will never be called unknowingly.
Local and anonymous classes, as well as lambdas, capture local variables by value when they are created. Therefore, it is impossible for them to refer to themselves by capturing a local variable, because the value for pointing to themself does not exist yet at the time they are being created.
Code in local and anonymous classes can still refer to themselves using this. However, this in a lambda does not refer to the lambda; it refers to the this from the outside scope.
You could capture a mutable data structure, like an array, instead:
IntToDoubleFunction[] foo = { null };
foo[0] = x -> { return ( x == 0)?1:x* foo[0].applyAsDouble(x-1);};
though hardly an elegant solution.
If you find yourself needing to do this sort of thing often, another option is to create a helper interface and method:
public static interface Recursable<T, U> {
U apply(T t, Recursable<T, U> r);
}
public static <T, U> Function<T, U> recurse(Recursable<T, U> f) {
return t -> f.apply(t, f);
}
And then write:
Function<Integer, Double> fact = recurse(
(i, f) -> 0 == i ? 1 : i * f.apply(i - 1, f));
(While I did this generically with reference types, you can also make primitive-specific versions).
This borrows from an old trick in The Little Lisper for making unnamed functions.
I'm not sure I'd ever do this in production code, but it is interesting...
Answer is : You have to use a this before name variable calling applyAsDouble function :-
IntToDoubleFunction fact = x -> x == 0 ? 1 : x * this.fact.applyAsDouble(x-1);
if you make the fact final also it will work
final IntToDoubleFunction fact = x -> x == 0 ? 1 : x * this.fact.applyAsDouble(x-1);
We can use functional interface UnaryOperator here. A unary operator that always returns its input argument.
1) Just add this. before the name of the function, as in:
UnaryOperator<Long> fact = x -> x == 0 ? 1 : x * this.fact.apply(x - 1 );
This will hep to avoid “Cannot reference a field before it is defined”.
2) If you prefer a static field, just replace ' this ' with name of the class:
static final UnaryOperator<Long> fact = x -> x== 0? 1: x * MyFactorial.fact.apply(x - 1 );
public class LambdaExperiments {
#FunctionalInterface
public interface RFunction<T, R> extends Function<T, R> {
R recursiveCall(Function<? super T, ? extends R> func, T in);
default R apply(T in) {
return recursiveCall(this, in);
}
}
#FunctionalInterface
public interface RConsumer<T> extends Consumer<T> {
void recursiveCall(Consumer<? super T> func, T in);
default void accept(T in) {
recursiveCall(this, in);
}
}
#FunctionalInterface
public interface RBiConsumer<T, U> extends BiConsumer<T, U> {
void recursiveCall(BiConsumer<T, U> func, T t, U u);
default void accept(T t, U u) {
recursiveCall(this, t, u);
}
}
public static void main(String[] args) {
RFunction<Integer, Integer> fibo = (f, x) -> x > 1 ? f.apply(x - 1) + f.apply(x - 2) : x;
RConsumer<Integer> decreasingPrint = (f, x) -> {
System.out.println(x);
if (x > 0) f.accept(x - 1);
};
System.out.println("Fibonnaci(15):" + fibo.apply(15));
decreasingPrint.accept(5);
}
}
During my tests, this is the best that i could achieve for local recursive lambdas.
They can be used in streams as well but we loose the easyness of the target typing.
One solution is to define this function as an INSTANCE attribute.
import java.util.function.*;
public class Test{
IntToDoubleFunction fact = x -> { return ( x == 0)?1:x* fact.applyAsDouble(x-1);};
public static void main(String[] args) {
Test test = new Test();
test.doIt();
}
public void doIt(){
System.out.println("fact(3)=" + fact.applyAsDouble(3));
}
}
Another version using accumulator so that recursion can be optimised.
Moved to Generic interface definition.
Function<Integer,Double> facts = x -> { return ( x == 0)?1:x* facts.apply(x-1);};
BiFunction<Integer,Double,Double> factAcc= (x,acc) -> { return (x == 0)?acc:factAcc.apply(x- 1,acc*x);};
Function<Integer,Double> fact = x -> factAcc.apply(x,1.0) ;
public static void main(String[] args) {
Test test = new Test();
test.doIt();
}
public void doIt(){
int val=70;
System.out.println("fact(" + val + ")=" + fact.apply(val));
}
}
You can define a recursive lambda as an instance or class variable:
static DoubleUnaryOperator factorial = x -> x == 0 ? 1
: x * factorial.applyAsDouble(x - 1);
for example:
class Test {
static DoubleUnaryOperator factorial = x -> x == 0 ? 1
: x * factorial.applyAsDouble(x - 1));
public static void main(String[] args) {
System.out.println(factorial.applyAsDouble(5));
}
}
prints 120.0.
public class Main {
static class Wrapper {
Function<Integer, Integer> f;
}
public static void main(String[] args) {
final Wrapper w = new Wrapper();
w.f = x -> x == 0 ? 1 : x * w.f.apply(x - 1);
System.out.println(w.f.apply(10));
}
}
A bit like the very first reply ...
public static Function<Integer,Double> factorial;
static {
factorial = n -> {
assert n >= 0;
return (n == 0) ? 1.0 : n * factorial.apply(n - 1);
};
}
The following works but it does seem arcane.
import java.util.function.Function;
class Recursion{
Function<Integer,Integer> factorial_lambda; // The positions of the lambda declaration and initialization must be as is.
public static void main(String[] args) {new Recursion();}
public Recursion() {
factorial_lambda=(i)->{
if(i==1)
return 1;
else
return i*(factorial_lambda.apply(i-1));
};
System.out.println(factorial_lambda.apply(5));
}
}
// Output 120
I heard at the JAX this year, that "lambads do not support recursion". What is meant with this statement is that the "this" inside the lambda always refer to the surrounding class.
But I managed to define - at least how I understand the term "recursion" - a recursive lambda and it goes like that:
interface FacInterface {
int fac(int i);
}
public class Recursion {
static FacInterface f;
public static void main(String[] args)
{
int j = (args.length == 1) ? new Integer(args[0]) : 10;
f = (i) -> { if ( i == 1) return 1;
else return i*f.fac( i-1 ); };
System.out.println( j+ "! = " + f.fac(j));
}
}
Save this inside a file "Recursion.java" and with the two commands "javac Recursion.java" and "java Recursion" it worked for me.
The clou is to keep the interface that the lambda has to implement as a field variable in the surrounding class. The lambda can refer to that field and the field will not be implicitly final.
You can also define it as a local variable by creating a final array of size one (of say Function[]) and then assign the function to element 0. Let me know if you need the exact syntax
Given the fact that "this" in the lambda refers to the containing class, the following compiles with no errors (with added dependencies, of course):
public class MyClass {
Function<Map, CustomStruct> sourceToStruct = source -> {
CustomStruct result;
Object value;
for (String key : source.keySet()) {
value = source.get(key);
if (value instanceof Map) {
value = this.sourceToStruct.apply((Map) value);
}
result.setValue(key, value);
}
return result;
};
}
Another recursive factorial with Java 8
public static int factorial(int i) {
final UnaryOperator<Integer> func = x -> x == 0 ? 1 : x * factorial(x - 1);
return func.apply(i);
}
#IanRobertson Nicely done, in fact you can move the static 'factory' into the body of the interface itself thus encapsulating it entirely:
public static interface Recursable<T, U> {
U apply(T t, Recursable<T, U> r);
public static <T, U> Function<T, U> recurseable(Recursable<T, U> f) {
return t -> f.apply(t, f);
}
}
This is the cleanest solution/answer I have seen so far ... especially since the invocation of "fact" is written "naturally": fac.apply(n) which is what you would expect to see for a unary function like fac()
You can define generic Fixed-point combinator like this.
public static <T, R> Function<T, R> fixedPointCombinator(Function<Function<T, R>, Function<T, R>> f) {
return new Function<T, R>() {
#Override
public R apply(T n) {
return f.apply(this).apply(n);
}
};
}
And
Function<Function<Integer, Double>, Function<Integer, Double>> fact =
self -> n -> n == 0 ? 1 : n * self.apply(n - 1);
System.out.println(fixedPointCombinator(fact).apply(10));
output:
3628800.0
The problem, is that lambda-functions want to operate on final variables, while we need a mutable Function-reference that can be replaced with our lambda.
The easiest trick, appears to be to, to define the variable as a member variable, and the compiler won't complain.
I changed my example to use IntUnaryOperator instead of IntToDoubleFunction, since we're just operating on Integers anyway here.
import org.junit.Test;
import java.util.function.IntUnaryOperator;
import static org.junit.Assert.assertEquals;
public class RecursiveTest {
private IntUnaryOperator operator;
#Test
public void factorialOfFive(){
IntUnaryOperator factorial = factorial();
assertEquals(factorial.applyAsInt(5), 120); // passes
}
public IntUnaryOperator factorial() {
return operator = x -> (x == 0) ? 1 : x * operator.applyAsInt(x - 1);
}
}
Here is a solution that does not rely on a side effect. To make the purpose interesting, let's say that you want to abstract over the recursion (otherwise the instance field solution is perfectly valid).
The trick is to use an anonymous class to get the 'this' reference:
public static IntToLongFunction reduce(int zeroCase, LongBinaryOperator reduce) {
return new Object() {
IntToLongFunction f = x -> x == 0
? zeroCase
: reduce.applyAsLong(x, this.f.applyAsLong(x - 1));
}.f;
}
public static void main(String[] args) {
IntToLongFunction fact = reduce(1, (a, b) -> a * b);
IntToLongFunction sum = reduce(0, (a, b) -> a + b);
System.out.println(fact.applyAsLong(5)); // 120
System.out.println(sum.applyAsLong(5)); // 15
}
You can create a recursive function using this class:
public class Recursive<I> {
private Recursive() {
}
private I i;
public static <I> I of(Function<RecursiveSupplier<I>, I> f) {
Recursive<I> rec = new Recursive<>();
RecursiveSupplier<I> sup = new RecursiveSupplier<>();
rec.i = f.apply(sup);
sup.i = rec.i;
return rec.i;
}
public static class RecursiveSupplier<I> {
private I i;
public I call() {
return i;
}
}
}
And then you can use any functional interface in just 1 line using a lambda and the definition of your functional interface like the following:
Function<Integer, Integer> factorial = Recursive.of(recursive ->
x -> x == 0 ? 1 : x * recursive.call().apply(x - 1));
System.out.println(factorial.apply(5));
I found it very intuitive and easy to use.
Came accross this question during a lecture on Lambdas that used Fibonacci as a possible use case.
You can make a recursive lambda like this:
import java.util.function.Function;
public class Fib {
static Function<Integer, Integer> fib;
public static void main(String[] args) {
fib = (n) -> { return n > 1 ? fib.apply(n-1) + fib.apply(n-2) : n; };
for(int i = 0; i < 10; i++){
System.out.println("fib(" + i + ") = " + fib.apply(i));
}
}
}
What do you have to keep in mind?
Lambdas are evaluated on execution -> they may be recursive
Using a lambda-variable inside of another lambda requires the
variable to be initialized -> before defining a recursive lambda you
must define it with a foo-value
using a local lambda-variable inside a lambda requires the variable
to be final, thus it cannot be redefined -> use a class/ object
variable for the lambda as it is initialized with a default value
Picking up on the common theme of answers here is that lambdas CAN be recursive, providing they have a fixed reference point (hence the class/interface based answers such as #assylias, #Andrey Morozov, #Ian Robertson, etc).
I really liked the answer from #000000000000000000000 with the member variable workaround but I have concerns if the intended lambda function wanted to reference other variables from the containing function's scope. Surely it'll be evaluating those local references at assignment and putting the resulting function into a member variable where it could be accessed by other methods in the class. That doesn't sound ... right (and could get quite interesting if the containing method itself is called recursively).
The following is a variation of the class-based solutions expressed in a form that's close to the OP's original one-line lambda but Eclipse doesn't complain about.
IntToDoubleFunction fact = new IntToDoubleFunction() {
#Override
public double applyAsDouble(int x) {
return x == 0 ? 1 : x * this.applyAsDouble(x-1);
}
};
The { } of course creates an anonymous class and thus a new scope with reference points for the lambda's evaluation with the added benefits of still being within containing function's own scope and thus "sibling" variables.
You could also define interface yourself wher you would just pass it itself as argument during call. E.g
interface MyOwnFunction<T,R>{
R apply(MyOwnFunction<T,R> self,T arg);
}
I don't have a Java8 compiler handy, so can't test my answer. But will it work if you define the 'fact' variable to be final?
final IntToDoubleFunction fact = x -> {
return ( x == 0)?1:x* fact.applyAsDouble(x-1);
};

Sorting objects of generic class by type argument

I've made a very simple generic class that store 2 variable of the same type, like this:
public MyClass<T>
{
private T v1;
private T v2;
public MyClass(T v1, T v2)
{
this.v1 = v1;
this.v2 = v2;
{
}
Now I need to implement, trough another non-generic class, a method that take an Object list of different types as input and give as output a list of MyClass<T> with couples of the same type.
My problem is that I cannot see a way to make something like this without knowing what types I'm working with, how do I instantiate the right type of MyClass every time?
I've come this far without getting errors from eclipse
public List<MyClass<?>> match()
{
List<MyClass<?>> list = new ArrayList<MyClass<?>>();
for(Object obj : this.list)//not the same list it's a parameter of the
{ //non-generic class
for(Object obj2 : this.list)
{
if(!(obj == obj2)&&obj.getClass().equals(obj2.getClass()))
{
MyClass<Object> couple = new MyClass<Object>(obj, obj2);
insertCouple(couple, list);
}
}
}
insertCouple is a private method that check if the couple are already in the output list, I've tried to implements Comparable on MyClass but made the coding even more complex.
As you can see I'm forced to stay generic but I can see there are problems with it.
If there isn't a method to find and fill the specific type at run time, how do I have to wrote that to make it possible trough generics?
You cannot decide which type of MyClass object to create at runtime (depending on the class of the matched objects), since all generic types are erased at compile time. You can read more on type erasure at:
http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
From what I could gather in the comments, the solution is to build a list of pairs of elements from input list, based on a predicate.
class Match<T>
{
T a, b;
Match(T a, T b)
{
this.a = a;
this.b = b;
}
}
<T> List<Match<T>> match(List<T> list)
{
List<Match<T>> matchList = new ArrayList<Match<T>>();
for(T a : list)
{
for(T b : list)
{
if(a != b && a.getClass().equals(b.getClass()))
{
matchList.add(new Match<T>(a, b));
}
}
}
return matchList;
}
I believe I met your requirements:
Now I need to implement, trough another non-generic class, a method that take an Object list of different types as input and give as output a list of MyClass with couples of the same type.
The class containing the code above does not need be generic, and so the match method can be invoked with implicit specification of T, as in, you don't need to know T or specify it, in fact you can simply call match on a List<Object> or List (legacy code) if you will. The only restriction is that, the list you will get in return is typed as List<Match<K>> when you call match on a List<K>, but that's a good thing - generics are well applicable here.
You can even customize match, by having it operate on a predicate parameter:
class Predicate
{
<T> boolean eval(T a, T b)
{
return a != b && a.getClass().equals(b.getClass());
}
}
<T> List<Match<T>> match(List<T> list, Predicate predicate)
{
List<Match<T>> matchList = new ArrayList<Match<T>>();
for(T a : list)
{
for(T b : list)
{
if(predicate.eval(a, b))
{
matchList.add(new Match<T>(a, b));
}
}
}
return matchList;
}
As a final advice, avoid omitting type parameters for generic classes - that's a practice reserved for legacy code, and otherwise may indicate a logic problem with your code. It's the easiest thing to do - put Object or ? everywhere, but it is better to try to find true matching types for these generic specifications, in most cases.

Java Generics: How does Java determine whether it's a set or get process for a bounded wildcard

Ok guys. This is a revision
class Node<E> { // (1)
private E data; // Data (2)
private Node<E> next; // Reference to next node (3)
Node(E data, Node<E> next) { // (4)
this.data = data;
this.next = next;
}
public void setData(E e) {} // (5)
public void xxxData(E e) {} // (6)
public E getData(E e) {return null;} // (7)
public static void main(String [] args) {
Node<? extends Integer> n1 = new Node<Integer>(1,null); //8
Node<? super Integer> n2 = new Node<Integer>(1,null); //9
n1.setData(new Integer(1)); //10 compiler error
n1.xxxData(new Integer(1)); //11 compiler error
n2.setData(new Integer(1)); //12 ok
}
}
Here's a rewrite hopefully i can convey my confusion nicely.
1. n1 is upper bounded wildcard. So this wont allow adding of records. Clause 10 proves this.
2. clause 11 also proves that method names (in this case 'SET' to determine adding of records) not being used since xxxData method gives the same compiler error.
3. n2 is lower bounded wildcard. Since method names doesn't play a role here, how does compiler knows that setData method can be used on n2 (since n2 is a lower bounded wildcard and this wildcard allows for adding of records)? Basically what the difference on method setData on clause 10 and 12?
Bear in mind nothing happens in those methods. It's empty or returning null.
If I understood your question properly, I guess it's because Integer is both super- and subtype to itself.
Yes, you are confusing three things:
java method names are just names, you can call them anything you want
there is a convention in Java to use what are called getters and setters. If you have a field (data or next in your example), then you define two methods:
.
public void setData(E data) {
this.data = data;
}
public E getData() {
return this.data;
}
This convention is called Java Beans. You'd do the same for node by the way.
3) Java selects the method to call based upon the types of the parameters that you pass to the method. This is called method overloading. It means that you can define things like:
public void setFile(String name) {
// do something here
}
public void setFile(File file) {
// do something here
}
so you can call:
setFile(new File("barbar"));
or
setFile("c:\stuff");
and the correct method will be chosen.
The generic types that you have just confuse the situation even more :-)
Java doesn't care about get/set in the method name; it's all based on method parameter types. Consider
interface G<T>
T f1();
void f2(T t);
void f3();
Substitute T with different types, methods signatures are changed too; for example, G<Int> methods
Int f1();
void f2(Int t);
void f3();
So we can do the following
G<Int> o = ...;
Int i = o.f1();
o.f2(i);
o.f3();
What happens with wildcards? Actually compiler can't directly reason about wildcards; they must be replaced with fixed albeit unknown types; this process is called "wildcard capture".
For example, given a G<? super Int> type, compiler internally treats it as G<W>, where W is an unknown supertype of Int. G<W> has methods
W f1();
void f2(W t);
void f3();
So we can do
G<? super Int> o = ...;
Object i = o.f1(); // f1() returns W, which is subtype of Object
o.f2( new Int(42) ); // f2() accepts W; Int is a subtype of W, accepted.
o.f3();
Similarly
G<? extends Int> o = ...; // G<W>, where W is a subtype of Int
Int i = o.f1(); // f1() returns W, which is subtype of Int
o.f2( new Int(42) ); // error: f2() accepts W; Int is NOT a subtype of W
o.f3();
I think i have the answer to this problem. It's true that method name doesn't play a role here but rather whether the reference assignment is valid.
Compiler error for clause 10 & 11 is due to the following in terms of parameter assignment.
? extends Integer = Integer
One cannot assign the Integer to ? extends Integer since the ? extends Integer could have type which is lower than Integer (figuratively speaking).
Of course this works for clause 12.
The question really changed now... The answer to this is PECS
(or here, page 28)
Also see, What is PECS (Producer Extends Consumer Super)? or How can I add to List<? extends Number> data structures?

Categories