Hi Eric,
I am just learning Java and am trying to write a method that does
something like
//===========================================
public Static List find(double[] array,double val,String relationalOp)
It's a good example method. Unfortunately, Java is not very good at
handling such cases, because it does not treat methods (or operations)
as normal values. You cannot directly pass a method as an argument to
another method.
The closest you could get would be to use anonymous classes as a
substitute, as in the following (beware, very verbose)!
import java.util.*;
public class Main {
abstract static class DoubleOp
{
abstract boolean test(double x, double y);
}
public static List find(double[] array,double val, DoubleOp op){
List list = new ArrayList();
for (int m = 0;m < array.length;m++) {
// The following line is the problem
if (op.test(array[m], val)) {
list.add(new Double(array[m]));
}
}
return list;
}
public static void main(String[] args) {
double[] numbers = new double[]{ -10, -1, 0, 2, 5, 11 };
DoubleOp leq = new DoubleOp() {
boolean test(double x, double y) {
return x < y;
}
};
List negative = find(numbers, 0, leq);
System.out.println("Negative numbers: " + negative);
DoubleOp neq = new DoubleOp() {
boolean test(double x, double y) {
return x != y;
}
};
List nonZero = find(numbers, 0, neq);
System.out.println("Non-zero numbers: " + nonZero);
}
}
It is much easier if you can use a language that support methods as
values. For instance, here is the same code in the Nice language, which
is an extension of Java with many features, including method values (I
am one of the developers of Nice. You can find more about it at
http://nice.sf.net)
List<double> find(double[] array,double val,(double,double)->boolean op)
{
List<double> list = new ArrayList();
for (int m = 0;m < array.length;m++) {
// The following line was the problem
if (op(array[m], val)) {
list.add(array[m]);
}
}
return list;
}
void main(String[] args)
{
double[] numbers = [ -10, -1, 0, 2, 5, 11 ];
let negative = find(numbers, 0, (double x,double y)=> x < y);
System.out.println("Negative numbers: " negative);
let nonZero = find(numbers, 0, (double x,double y)=> x != y);
System.out.println("Non-zero numbers: " nonZero);
}
Some comments:
(double,double)->boolean
This is the type of a method, which has two arguments of type
double, and returns a boolean.
let negative =
This is a way to declare a local variable, letting the compiler
find what is its type.
(double x,double y)=> x < y
This is an expression that represents the '<' comparison on doubles.
One way to generalize your method find is to give it only two arguments:
the array of number, and a method with _one_ argument of type double,
returning a boolean to say if that number should be included in the
results. This generalization is what we call 'filter'. So this code
could be simply rewritten as:
void main(String[] args)
{
double[] numbers = [ -10, -1, 0, 2, 5, 11 ];
let negative = filter(numbers, (double x)=> x < 0);
System.out.println("Negative numbers: " negative);
let nonZero = filter(numbers, (double x)=> x != 0);
System.out.println("Non-zero numbers: " nonZero);
}
Enjoy!
Daniel
The Nice programming language:
http://nice.sf.net