【问题标题】:Hash table where key is string and value is function [duplicate]哈希表,其中键是字符串,值是函数[重复]
【发布时间】:2014-04-12 00:31:00
【问题描述】:

是否有可能实现散列,其中键是String,值是function。作为背景,我有一个程序有很多字符串比较,即

if(s.equalsIgnoreCase("london")  
   functionA();  
else if(s.equalsIgnoreCase("moscow")  
   functionB();  
else if(s.equalsIgnoreCase("delhi")  
   functionC();  
  ...  

等等。

但是这种实现是非常昂贵的(theta(n)),因为String 比较是针对所有if 语句进行的。如果我们有一个哈希实现,其中键是String,值是function,我们可以调用类似

function = hash.Get("moscow");    
function(); 

它的复杂度很好(theta(log(1)))

可以这样做吗?

【问题讨论】:

  • 您使用什么语言? Java 还是 C++?
  • 目前我正在使用java。但我认为答案对任何语言都有帮助。
  • Java 和 C++ 是完全不同的语言,具有完全不同的特性。选择一个。
  • 我已经从标签中删除了 C++。请具体回答java

标签: java hash


【解决方案1】:

您可以将它们存储在Map<String, Runnable> 中。然后用 java

map.put("london", new Runnable() {
    public void run() { functionA(); }
});

或者使用 java 8,假设是静态方法:

map.put("london", YourClass::functionA);

或者使用实例方法:

map.put("london", this::functionA);

在所有三种情况下,您只需调用:

Runnable r = map.get(input.toLowerCase());
if (r != null) r.run();

【讨论】:

  • 我可以试一试,但为了完整起见,您能否在 Java 8 的情况下也添加 get,以及如何在 get 时调用它?
  • 感谢 assylias,我们如何在您的实现中调用该函数?
  • @assylias 实际上,即使在 Java8 中也是如此,Map 和您的示例 YourClass 是 Runnable。正确的?那么static..run() 不是静态的吧?
  • 并不是Runnable.run() 返回void。如果您希望该方法返回您将使用的内容Callable<V>
  • @sakura no YourClass 可以是任何类,只要functionA 的签名与run 的签名匹配,即返回static void functionA()
【解决方案2】:

在 C++ 中,您可以使用 std::map。 代码是这样的-

typedef (void)(*funcPtr)(); //declaring a compatible function pointer

std::map<std::string, funcPtr> myFunctions;

myFunctions["london"]=functionA;
myFunctions["paris"]=functionB;
//etc etc...

//calling the function
string wantedCity="london";
myFunction[wantedCity]();

编辑: 我看到你从标签中删除了 C++。 java也有类似的容器,你可以查一下它的方法。

【讨论】:

    【解决方案3】:

    在这种情况下,您可以使用 Guava Function 作为 Hastable 值。 更好的方法是使用 Java 多态性并在子类中定义此逻辑(函数 A、函数 B):

    public interface City {
        public void doSomething();
    }
    
    public class Example {
    
       private Map<String, City> cities;
    
       public void run(String param) {
           cities.get(param).doSomething();
       }
    }
    

    然后您根据需要为 City 定义尽可能多的实现(伦敦、莫斯科 ...),然后将它们的实例添加到地图中

    【讨论】:

      【解决方案4】:

      这是enum 的绝佳机会:

      enum City {
          London {
      
              @Override
              void function() {
                  System.out.println("Hello from England");
              }
      
          },
          Moscow  {
      
              @Override
              void function() {
                  System.out.println("Hello from Russia");
              }
      
          },
          Delhi {
      
              @Override
              void function() {
                  System.out.println("Hello from India");
              }
      
          };
      
          // They ALL must have a `function`.
          abstract void function ();
      }
      
      public void test() {
          City.valueOf("Moscow").function();
      }
      

      【讨论】:

        【解决方案5】:

        是的,只要您的方法返回一个值,这是可能的。例如:

        public SomeReturnType doSomthing(){
            return someReturnType;
        }
        

        并在您的哈希图中执行以下操作

        HashMap<String, SomeReturnType> hm = new HashMap<String, SomeReturnType>();
        

        在方法中进行比较时,布尔值可能是最佳选择。

        【讨论】:

        • 没有必要创建自己的类,实际上你展示的内容毫无意义。在 Java 中执行此操作的标准方法是使用 Callable&lt;V&gt; 接口。
        • 我不确定这有什么关系。我没有创建一个新课程。只需定义一个返回类型(SomeReturnType)就像你的 V.
        【解决方案6】:

        您可以使用 Java 反射。只需将函数名称作为值存储在HashMap 中,然后通过Method.invoke 调用它。

        Class.getMethod(String name, Class... parameterTypes)

        Method.invoke(Object obj, Object... args)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-23
          • 2013-05-02
          • 1970-01-01
          • 1970-01-01
          • 2013-08-04
          • 2012-10-03
          • 1970-01-01
          相关资源
          最近更新 更多