代码之家  ›  专栏  ›  技术社区  ›  Matt Ball

如何将字符串映射到Java中的函数?

  •  11
  • Matt Ball  · 技术社区  · 14 年前

    目前,我有一组Java类来实现 Processor 接口,意味着它们都有一个 processRequest(String key) 方法。我们的想法是每个班级都有几个(比如,<10)成员 Strings ,并且每一个都通过 processRequest 方法,如:

    class FooProcessor implements Processor
    {
        String key1 = "abc";
        String key2 = "def";
        String key3 = "ghi";
        // and so on...
    
        String processRequest(String key)
        {
            String toReturn = null;
            if (key1.equals(key)) toReturn = method1();
            else if (key2.equals(key)) toReturn = method2();
            else if (key3.equals(key)) toReturn = method3();
            // and so on...
    
            return toReturn;
        }
    
        String method1() { // do stuff }
        String method2() { // do other stuff }
        String method3() { // do other other stuff }
        // and so on...
    }
    

    你明白了。

    这对我来说很好,但是现在我需要一个从键到函数的运行时可访问的映射;不是每个函数 事实上 返回一个字符串(一些返回void),我需要动态访问每个类中每个函数的返回类型(使用反射),每个类都有一个键。我已经有一个经理知道所有的钥匙,但是 从键到函数的映射。

    我的第一反应是用 if-else 带有 Map<String, Function> 就像我在javascript中所做的那样。但是,Java不支持一流的功能,所以我运气不好。我可能会挖一个第三方库,让我使用一流的功能,但我还没有看到任何,我怀疑我需要一个完整的新库。

    我还想把这些 String 键到数组中并使用反射按名称调用方法,但我看到此方法的两个缺点:

    • 我的键必须与方法命名相同,或者以一种特定的、一致的方式命名,这样就很容易将它们映射到方法名。
    • 这似乎比 如果不是的话 我现在有陈述。效率是一个值得关注的问题,因为这些方法经常被调用,我希望最小化不必要的开销。

    TL;医生: 我正在寻找一个干净的,最小开销的方法来映射 某种程度上 Function 我可以调用的对象(类似于) getReturnType() 在。我不介意用第三方图书馆,如果它 真正地 符合我的需要。我也不介意使用反射,尽管我强烈希望每次执行方法查找时都避免使用反射-可能使用一些结合了 Map 带着反思。

    想一个好的方法得到我想要的?干杯!

    7 回复  |  直到 12 年前
        1
  •  1
  •   Matt Ball    12 年前

    你不能吗 String Method ?然后可以缓存需要执行的方法。

        2
  •  7
  •   Michael Aaron Safyan    14 年前

    没有任何一级的独立函数,但是您可以用一个接口来做您想要做的事情。创建一个表示函数的接口。例如,您可能有以下内容:

    public interface ComputeString
    {
        public String invoke();
    }
    

    然后您可以创建一个 Map<String,ComputeString> 你想要的东西。使用地图会比反射快得多,而且会提供更多的类型安全性,因此我建议以上内容。

        3
  •  4
  •   RoToRa    14 年前

    虽然您不能拥有第一类函数,但有一些匿名类可以基于接口:

    interface ProcessingMethod {
       String method();
    }
    
    Map<String, ProcessingMethod> methodMap = new HashMap<String, ProcessingMethod>();
    methodMap.put("abc", new ProcessingMethod() {
       String method() { return "xyz" }
    });
    methodMap.put("def", new ProcessingMethod() {
       String method() { return "uvw" }
    });
    
    methodMap.get("abc").method();
    

    或者你可以用scala:-)

        4
  •  1
  •   trashgod    14 年前

    example 使用 enum 命名函数和摘要 FunctionAdapter 在不反射的情况下调用具有可变数量同构参数的函数。这个 lookup() 函数只使用 Enum.valueOf ,但A Map 对于大量的函数来说可能是值得的。

        5
  •  0
  •   justkt    14 年前

    正如您所注意到的,您可以使用 Reflection API 但是,在你已经提出的问题的基础上,你会放松Java编译器的一些好处。将字符串包装在对象中并使用 Visitor pattern 解决你的问题?各 StringWrapper 只接受 Visitor 这是正确的方法,或者是沿着这些路线的东西。

        6
  •  0
  •   mjh2007    14 年前

    使用一个映射,其中键是字符串,值是实现包含方法()的接口的对象。这样,您就可以从映射中获取包含所需方法的对象。然后在对象上调用该方法。例如:

    class FooProcessor implements Processor{
    
        Map<String, FooMethod> myMap;
    
        String processRequest(String key){
            FooMethod aMethod = myMap.getValue(key);
            return aMethod.method();
        }        
    }
    
        7
  •  0
  •   Denis Tulskiy    14 年前

    怎么样 Method 从反射API类?可以根据名称、参数或返回类型查找类的方法。然后您只需调用method.invoke(这是参数)。

    这与您所说的javascript中的映射基本相同。