Working with ArrayList Functions in Java-8

Description of the problem: I want to be able to use an ArrayList from functions passed from another class (where the functions are defined in this other class). If the list of functions that can have different types of input and return are defined in one class, I want to be able to pass an ArrayList from some of them with possible duplicates as a parameter to some other constructor or method of the class and perform operations using them.

Description of the code: The code below is a very simplified example that does not make much sense from a design point of view. The focus of the problem lies in the getResult() method inside SomeClass and generally how to use the ArrayList from functions after they appear.

Trying to solve a problem: Implementing the getResult () method is an example of one of many attempts to use a list of functions. Again, please ignore the code design. This was done in such a way as to try to make an example of the problem as short as possible.

Simple tester class

 package com.Testing; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Function; public class Tester { public static void main(String[] args) { // Some functions Function<Integer, Integer> increment = (Integer input) -> { return input + 1; }; Function<Integer, Integer> decrement = (Integer input) -> { return input - 1; }; Function<Double, Double> timesPi = (Double input) -> { return input * 3.14; }; // list of Functions List<Function> availableMathOperations = new ArrayList<>(); List<Function> selectedMathOperations = new ArrayList<>(); // populate master list availableMathOperations.add(increment); availableMathOperations.add(decrement); availableMathOperations.add(timesPi); // Populate random selection list // // generate random binary number Random randomGenerator = new Random(); int randomNumber = randomGenerator.nextInt(availableMathOperations.size() * 2); boolean[] bits = new boolean[availableMathOperations.size()]; for (int j = 0; j < availableMathOperations.size(); j++) { bits[availableMathOperations.size() - 1 - j] = (1 << j & randomNumber) != 0; } // add math operations to selectedMathOperations based on binary number for (int j = 0; j < bits.length; j++) { if (bits[j]){ selectedMathOperations.add(availableMathOperations.get(j)); } } SomeClass someClass = new SomeClass(selectedMathOperations, 1.23); } } 

Another class

 package com.Testing; import java.util.List; import java.util.function.Function; public class SomeClass { List<Function> operations; double initialValue; public SomeClass(List<Function> newOperations, double newInitialValue){ operations = newOperations; initialValue = newInitialValue; } public double getResult(){ double result = 0.0; // problem method // perform the random list of operations using the initial value initially for(int i = 0; i < operations.size(); i++){ if(i == 0) result = operations.get(i)(initialValue); else result += operations.get(i)(result); } return result; } } 
+4
java function arraylist java-8
May 16 '15 at 9:45
source share
2 answers

method of the java.util.function.Function object - apply . You need to call it like this:

 operations.get(i).apply(initialValue) 

However, you are using raw Function , and therefore the result may be Object , and you will need to convert it to the appropriate type. Also, you cannot use the + (or += ) operator with it. I would suggest limiting the parameter types Number :

 List<Function<Number, ? extends Number>> operations = Arrays.asList( num -> num.intValue() + 1, num -> num.intValue() - 1, num -> num.doubleValue() * 3.14 ); // just an example list here public double getResult() { double result = 0.0; for (int i = 0; i < operations.size(); i++) { if (i == 0) { result = operations.get(i).apply(initialValue).doubleValue(); } else { result += operations.get(i).apply(result).doubleValue(); } } return result; } 
+5
May 16 '15 at 10:21
source share

I'm not sure I understand correctly, but I think the problem you are facing is how to call functions in a List ? The JavaDoc for the Function interface indicates that it has one non-abstract method, apply() , which you call to use the function, as follows:

 public double getResult(){ double result = 0.0; for(int i = 0; i < operations.size(); i++){ if(i == 0) result = operations.get(i).apply(initialValue); else result += operations.get(i).apply(result); } return result; } 

As an aside, this method can be removed a bit to make it easier:

 public double getResult() { double result = initialValue; //Not sure if this if-statement is a requirement, but it is to replicate //the functionality in the question if (operations.isEmpty()) { return 0.0; } for (Operation operation : operations) { result = operation.apply(result); } return result; } 

And as others said in the comments, you should use generics when traversing around List objects (I think you have to use something like List<Function<? extends Number, ? extends Number> )

0
May 16 '15 at 9:54
source share



All Articles