0

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

Derek Wang
  • 10,098
  • 4
  • 18
  • 39
mickey
  • 1

1 Answers1

0

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);
    }
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24
  • Hello, I don't understand if it is the clearer solution but it gives an 2 error (same) to me: method bar in class Test cannot be applied to given types; bar( ^ required: Foo,FooFunc found: reason: actual and formal argument lists differ in length – mickey Oct 12 '20 at 13:31
  • @mickey it doesn't give me any error, but it gives me 50100.0 and 150.0 – Maurice Perry Oct 12 '20 at 13:35
  • @mickey I don't see any class called `Test`. I have added the full file that I've used in an update to my post. – Maurice Perry Oct 12 '20 at 13:39
  • Sorry I was working. But in my first post code I had 2 more 'bar' functions. Those gave me error! (the 'bar's whithin 'method' function.....) Any improvement, maybe with lambd?. It is much more complicate than C language.... – mickey Oct 12 '20 at 13:48
  • @mickey Hi. Java is not C. There is no such thing as a function pointer in Java; only objects. – Maurice Perry Oct 12 '20 at 16:00