passing a function pointer to a method

43 views Asked by At

I've read some posts about function pointers but I still don't understand how to use 'function pointers' the best for my case. Also in this case It isn't clear to me the use of anonymous classes...

Here the code:

class Fitness {
  private List < Double > list;
  interface Foo {
    //public Foo;
    Object myFunc(Object arg);
    Object myFunc2(Object arg);
  }
  public Fitness(List < Double > list) {
    this.list = new ArrayList < Double > (list);
  }
  public void bar(Foo foo) {
    Object object = foo.myFunc(list);
    System.out.println(object);

    Object object2 = foo.myFunc2(list);
    System.out.println(object2);
  }
  public void method(String func) {
    if (func.equals("f1"))
      bar(
        new Foo() {
          public Object myFunc(Object arg) {
            return (Double)((List) arg).get(0) + 50.0;
          }
          public Object myFunc2(Object arg) {
            return (Double)((List) arg).get(0) + 50.0;
          }
        });
    else if (func.equals("f2"))
      bar(
        new Foo() {
          public Object myFunc(Object arg) {
            List < Double > l = (List < Double > ) arg;
            return l.get(0) / l.size();
          }
          public Object myFunc2(Object arg) {
            List < Double > l = (List < Double > ) arg;
            return l.get(0) / l.size();
          }
        });

  }
  public void fitness1() {
    bar(
      new Foo() {
        public Object myFunc(Object arg) {
          return (Double)((List) arg).get(0) + 50.0 * 1000;
        }
        public Object myFunc2(Object arg) {
          return (Double)((List) arg).get(0) + 50.0;
        }
      });
  }
}

class Example {
  public static void main(String[] args) {
    ArrayList < Double > listD = new ArrayList < Double > ();
    listD.add(100.0);
    listD.add(-1.0);
    listD.add(-5.0);
    Fitness t = new Fitness(listD);
    //t.method("f1");
    //t.method("f2");
    //t.method2();
    t.fitness1();
  }
}

What I would like is an object Fitness that call a fitness function according to some parameters. A fitness method should be able to take a list of int, double, even couple <int, String>.

I want to do a test: so I want to see the different results if I choose f1, f2, f3, f4. I am confused about how to code it.

Thanks in advance

1

There are 1 answers

5
Maurice Perry On

You can declare the following interface:

interface FooFunc {
    Object invoke(Foo foo, Object arg);
}

Then change slightly your bar() method:

public void bar(Foo foo, FooFunc func) {
    Object object = func.invoke(foo, list);
    System.out.println(object);
}

... and your fitness1() method:

public void fitness1(FooFunc func) {
    bar(
            new Foo() {
        public Object myFunc(Object arg) {
            return (Double) ((List) arg).get(0) + 50.0 * 1000;
        }

        public Object myFunc2(Object arg) {
            return (Double) ((List) arg).get(0) + 50.0;
        }
    }, func);
}

Now, from your main() method, you can do:

    Fitness t = new Fitness(listD);
    t.fitness1(Fitness.Foo::myFunc);
    t.fitness1(Fitness.Foo::myFunc2);

Isn't it great?

UPDATE: Complete file

import java.util.ArrayList;
import java.util.List;

class Fitness {

    private List<Double> list;

    interface Foo {

        //public Foo;
        Object myFunc(Object arg);

        Object myFunc2(Object arg);
    }

    interface FooFunc {
        Object invoke(Foo foo, Object arg);
    }

    public Fitness(List<Double> list) {
        this.list = new ArrayList<Double>(list);
    }

    public void bar(Foo foo, FooFunc func) {
        Object object = func.invoke(foo, list);
        System.out.println(object);
    }

    public void fitness1(FooFunc func) {
        bar(
                new Foo() {
            public Object myFunc(Object arg) {
                return (Double) ((List) arg).get(0) + 50.0 * 1000;
            }

            public Object myFunc2(Object arg) {
                return (Double) ((List) arg).get(0) + 50.0;
            }
        }, func);
    }
}

public class Example {

    public static void main(String[] args) {
        ArrayList<Double> listD = new ArrayList<>();
        listD.add(100.0);
        listD.add(-1.0);
        listD.add(-5.0);
        Fitness t = new Fitness(listD);
        t.fitness1(Fitness.Foo::myFunc);
        t.fitness1(Fitness.Foo::myFunc2);
    }
}