Java pass method reference as parameter to other method

前端 未结 5 1423
暗喜
暗喜 2021-02-04 07:53

I am trying to pass a selected \"get\"-method of class A to a method in class B. I have checked out Java Pass Method as Parameter, but I was not able to adopt the interface appr

相关标签:
5条回答
  • 2021-02-04 08:17

    MethodReference is a class for reflection purpose. Your code actually need a lambda-like object, which shall be a single method interface in Java 8.

    Without Java 8 or reflection there is no way to directally meet your need though. But you can always pass some internal representation of the method to another calss, and to do so you have to write code to process this internal representation.

    0 讨论(0)
  • 2021-02-04 08:25

    You can use Command Design Pattern

    for more info :

    https://en.wikipedia.org/wiki/Command_pattern http://www.tutorialspoint.com/design_pattern/command_pattern.htm

    0 讨论(0)
  • 2021-02-04 08:33

    There is a workaround: Scala java apis.

    I use Apache Spark and scala offers a series of Anonymous Functions (Function, Function2) which are available since Java 1.5, if I'm not mistaken (although I use it with Java 1.7).
    Here is an answer talking about this. Because otherwise the "Function" class is available only from Java 1.8

    0 讨论(0)
  • 2021-02-04 08:38

    Your getX() methods can be seen as a Function that accepts a DataStore instance and returns a float.

    In Java 8 you can represent them with method references :

        float[] aArray = getValuesAsArray(dataMap, DataStore::getA);
        float[] bArray = getValuesAsArray(dataMap, DataStore::getB);
        float[] cArray = getValuesAsArray(dataMap, DataStore::getC);
    

    Then your getValuesAsArray will accept a Function<DataStore,Float> parameter and execute the function :

    private static float[] getValuesAsArray(Map<Integer, DataStore> dataMap, Function<DataStore,Float> func) {
        int i = 0;
        int nMap = dataMap.size();
        float[] fArray = new float[nMap];
        for (Map.Entry<Integer, DataStore> entry : dataMap.entrySet()) {
            DataStore ds = entry.getValue();
            fArray[i] = func.apply(ds);
            i++;
        }
        return fArray;
    }
    

    Without using Java 8, you can define your own interface that contains a method that accepts a DataStore instance and returns a float. Then, instead of using Java 8 method references, you would have to pass to your getValuesAsArray method an implementation of that interface (you could use an anonymous class instance implementing the interface) which calls one of the getX() methods.

    For example :

    public interface ValueGetter
    {
        public float get (DataStore source);
    }
    
    float[] aArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getA();}});
    float[] bArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getB();}});
    float[] cArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getC();}});
    

    And

    private static float[] getValuesAsArray(Map<Integer, DataStore> dataMap, ValueGetter func) {
        int i = 0;
        int nMap = dataMap.size();
        float[] fArray = new float[nMap];
        for (Map.Entry<Integer, DataStore> entry : dataMap.entrySet()) {
            DataStore ds = entry.getValue();
            fArray[i] = func.get(ds);
            i++;
        }
        return fArray;
    }
    
    0 讨论(0)
  • 2021-02-04 08:38

    Awhile ago I used java.util.concurrent.Callable but it doesn't seem to work out, thanks to @Eran.

    Instead, you can use Java 8's java.util.function.Function, like so (without the lambdas):

    public static void main(String[] args) {
     //...
        getValuesAsArray(dataMap, new Function<DataStore,Float>(){ public Float apply(DataStore input) { return input.getA(); }});
        getValuesAsArray(dataMap, new Function<DataStore,Float>(){ public Float apply(DataStore input) { return input.getB(); }});
        getValuesAsArray(dataMap, new Function<DataStore,Float>(){ public Float apply(DataStore input) { return input.getC(); }});
    }
    
    private static float[] getValuesAsArray(Map<Integer, DataStore> dataMap, Function<DataStore, Float> function) {
        int i = 0;
        int nMap = dataMap.size();
        float[] fArray = new float[nMap];
        for (Map.Entry<Integer, DataStore> entry : dataMap.entrySet()) {
            DataStore ds = entry.getValue();
            fArray[i] = function.apply(ds);
            i++;
        }
        return fArray;
    }
    
    0 讨论(0)
提交回复
热议问题