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

问题描述 投票:0回答:8

目前,我有一堆实现

Processor
接口的 Java 类,这意味着它们都有一个
processRequest(String key)
方法。这个想法是每个类都有一些(例如,<10) member
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

语句替换此映射,就像我在 Javascript 中所做的那样。但是,Java 不支持一等函数,所以我运气不好。我可能可以找到一个第三方库,让我可以使用一流的函数,但我还没有看到任何库,而且我怀疑我是否需要一个全新的库。


我还考虑过将这些
Map<String, Function>
键放入数组中,并使用反射按名称调用方法,但我发现此方法有两个缺点:

我的键必须以与方法相同的名称命名 - 或者以特定的、一致的方式命名,以便可以轻松地将它们映射到方法名称。

这似乎比我现在的
    String
  • 声明慢得多。效率是一个值得关注的问题,因为这些方法往往会被频繁调用,而我希望最大限度地减少不必要的开销。
  • 
    
  • TL; DR:
我正在寻找一种干净、开销最小的方法来将
if-else

映射到某种 String 对象,我可以在该对象上调用和调用(类似)

Function
。如果第三方库“真的”符合我的需求,我并不特别介意使用它。我也不介意使用反射,尽管我强烈希望避免每次进行方法查找时都使用反射 - 也许使用一些将
getReturnType()
与反射相结合的缓存策略。

有什么好方法可以得到我想要的东西吗?干杯!
没有任何一流的独立功能,但您可以通过界面做您想做的事情。创建一个代表您的功能的界面。例如,您可能有以下内容:

Map

java string reflection functional-programming
8个回答
8
投票
public interface ComputeString { public String invoke(); }

对象。使用贴图会比反射快得多,并且还会提供更多的类型安全性,所以我建议采用上述方法。


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


Map<String,ComputeString>


4
投票

你不能对

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();


1
投票
String

吗?然后就可以缓存需要执行的方法了。

    
示例
使用命名函数的

Method

1
投票
enum

来调用具有可变数量同质参数的函数,而无需反射。 FunctionAdapter 函数仅使用

lookup()
,但对于大量函数来说,
Enum.valueOf
可能是值得的。
    
正如您所注意到的,您可以使用 
Reflection API
做您想做的事情,但是除了您已经遇到的问题之外,您还失去了 Java 编译器的一些好处。 将您的字符串包装在一个对象中并使用

Visitor模式

0
投票
Map

只会接受具有正确方法或类似方法的 StringWrapper

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

Visitor


0
投票

反射 API 中的

Method
 类怎么样?您可以根据名称、参数或返回类型查找类的方法。然后你只需调用 Method.invoke(this,parameters) 即可。

0
投票

class FooProcessor implements Processor{ Map<String, FooMethod> myMap; String processRequest(String key){ FooMethod aMethod = myMap.getValue(key); return aMethod.method(); } }


0
投票
	
© www.soinside.com 2019 - 2024. All rights reserved.