Reputation: 23
I would like to make more of an effort to use Java 8's functional features and shift my thinking towards that paradigm; however, I'm not quite sure how to reconcile this scenario.
For example I recently wrote something similar to this:
public class ExampleClass {
private ExampleData exampleData;
private Function<ExampleData, Boolean> workFunction;
public ExampleData getExampeData() {
return exampleData;
}
public void setExampleData(ExampleData exampleData) {
this.exampleData = exampleData;
}
public Function<ExampleData, Boolean> getWorkFunction() {
return workFunction;
}
public void setWorkFunction(Function<ExampleData, Boolean> workFunction) {
this.workFunction = workFunction;
}
}
then I proceed to use it like so...
public class Worker implements Callable {
private final ExampleClass exampleClass;
// ExampleClass serves as a container for the function and it's
// input data in order to minimize the number of arguments
// passed to this constructor. Otherwise would be
// public Worker(ExampleData exampleData, Function<T, R> workFunction, ...) {
// Note: using "..." here to represent more args.
public Worker(ExampleClass exampleClass, ...) {
this.exampleClass = exampleClass;
...
}
@Override
public void call() {
final Boolean isComplete = exampleClass.getWorkFunction().apply(exampleClass.getExampleData());
if (isComplete) {
...
}
...
}
}
Would something like the above be preferred over what I would consider the more traditional approach?
public class ExampleClass {
private ExampleData exampleData;
public ExampleClass(ExampleData exampleData) {
this.exampleData = exampleData;
}
public Boolean work() {
return isComplete(exampleData);
}
}
and the implementing class...
public class Worker implements Callable {
private ExampleClass exampleClass;
public Worker(ExampleClass exampleClass, ...) {
this.exampleClass = exampleClass;
...
}
@Override
public void call() {
final Boolean isComplete = exampleClass.work();
if (isComplete) {
...
}
...
}
}
If I'm completely off base, what would be a proper functional solution using Java 8?
Update: Lets say my example doesn't return a Boolean. In the context of functional programming with Java 8, is it better to explicitly pass a function as a class level argument or is it better to just use the traditional object oriented way of just passing another class that performs that function?
Upvotes: 2
Views: 277
Reputation: 399
The point of Functional programming is that The function must be treated as an object.
but you know, function(method) is not object in java. it is differ to javascript.
so, we should use interface called Predicate.
List<Apple> apples = new ArrayList<>();
you want to get weight apples. originally,
List<Apple> weightApples = new ArrayList<>();
for(int i = 0; 9< apples.size(); i++){
if(apples.getWeight() > 10){
weightApples.add(apples.get(i));
}
}
this code.
in functional programming, function is be 'pure function'.
in pure function, You should avoid using external variables in functions.
and, we dont care function's logic in 'the line using function'
first, we need predicdate interface.
interface Predicate<T>{
public boolean pass(T t);
}
by generic, we can extend object type.
we can make filter.
public static <T> List<T> filter(List<T> list, Predicate<T> predicate){
List<T> result = new ArrayList<>();
for(T el : list){
if(predicate.pass(el)){
result.add(el);
}
}
return result;
}
the pass() is not implemented not yet.
it can implemented by annonymous class.
finally, method is treated like object by use lamda!
filter(apples, (Apple apple) -> apple.getWeight()>10);
i'm not people in english, so it is poor english.
but i hope it is helpful for you! thanks.
Upvotes: 1
Reputation: 14328
First of all, a function that accepts one argument and returns a boolean should implement Java 8 Predicate
.
However, in my opinion, predicates were not meant to replace any and all if
statements. They are meant to be used as filters in Java 8's collection streams. The example you provided does not seem to fit this situation.
Upvotes: 0