【问题标题】:Maps : In Java Maps can I assign a function to the value in the <K,V> pair?Maps:在 Java Maps 中,我可以为 <K,V> 对中的值分配一个函数吗?
【发布时间】:2013-07-10 17:00:17
【问题描述】:

我有一组字符串,我将用作键,对于特定字符串,我希望调用一个函数。那么是否可以将函数分配给pair中的值?

exampleMap.get("SOME_STRING"); // should call a function abc();

【问题讨论】:

  • 唯一可行的方法是实现您自己的地图。 Java 中的标准开箱即用 Map 实现不允许这样的事情。
  • 不是,是的,但不像你正在尝试的那样。你必须使用反射,然后你应该问你的设计发生了什么
  • 为什么不使用策略模式并将其作为值存储在 hashmap 中。

标签: java hashmap


【解决方案1】:

将您的函数封装在 Java 接口中:

public interface Task {
    void doSomething();
}

然后用这个接口的实例填充地图:

map.put("someString", new Task() {
    @Override
    public void doSomething() {
        System.out.println("foo");
    }
});
map.put("someOtherString", new Task() {
    @Override
    public void doSomething() {
        System.out.println("bar");
    }
});

然后调用与给定字符串s关联的函数(任务):

map.get(s).doSomething();

【讨论】:

  • 你比我早了 19 秒!
  • 但这只有在您还可以控制使用地图的代码时才有效(因为现在必须调用doSomething,而以前没有这样做过)。
  • 也许我误解了这个问题。我回答“是否可以为该对中的值分配一个函数”。如果 OP 希望每次调用 get() 时都调用某个函数,那么它就不再是 Map。
  • 如何对已经存在的类执行此操作?我不想做一个新的,只是执​​行一个现有的方法。
【解决方案2】:

不,java 还不支持任何方法对象。您可以使用反射或尝试用枚举常量替换您的字符串并调用它们的方法。

【讨论】:

    【解决方案3】:

    Java 不直接支持它,但您可以使用接口间接支持它。

    public interface Funct {
      public void apply();
    }
    

    然后当您想将其用作值时,请执行类似..

    Map<String, Funct> aMap = new HashMap<String, Funct>();
    aMap.put("foo", new Funct() { public void apply() { System.out.println("bar"); } });
    

    【讨论】:

      【解决方案4】:

      如果您希望这对 Map 的用户是透明的,您必须实现自己的 Map。

      【讨论】:

        【解决方案5】:

        如果你想要这种行为,你应该定义你自己的类。

        该类至少应实现以下接口:

        interface ApplicativeMap<K,V>{
          void put(K key, Function<V> producer);
          V get(K key);
        

        其中Function&lt;V&gt; 应该是公开V apply() 方法的接口。

        您的实现应该类似于以下内容:

        类 ApplicativeMapImplementation 实现 ApplicativeMap{ 私有 Map> 函数;

         public void put(K key, Function<V> producer){
           functions.put(key, producer);
         }
        
         public V get(K key){
           if(functions.containsKey(key)){
             return functions.get(key).apply();
           } else{
             throw new NoSuchElementException();
           }
         }
        

        【讨论】:

          【解决方案6】:

          您可以使用反射来做到这一点。考虑以下代码。

          Map<String, Method> map = new HashMap<String, Method>();
          SomeClass obj = new Someclass();
          Method method = null;
          try {
              method = obj.getClass().getMethod("someMethod", param1.class, param2.class, ...);
          } catch (SecurityException e) {
          } catch (NoSuchMethodException e) {
          }   
          map.put("someMethod", method);
          
          try {
              (map.get("someMethod")).invoke(obj, arg1, arg2, ...);
          } catch (IllegalArgumentException e) {
          } catch (IllegalAccessException e) {
          } catch (InvocationTargetException e) {
          }
          

          SomeClass内部要调用的方法

          public class SomeClass    {
          // Other class contents
              public void someMethod()    {
              // Target method contents
              }
          }
          

          使用上述逻辑的示例代码:

          import java.lang.reflect.InvocationTargetException;
          import java.lang.reflect.Method;
          import java.util.HashMap;
          import java.util.Map;
          
          public class Temp3 {
              public static void main(String[] args) {
                  Map<String, Method> map = new HashMap<String, Method>();
                  Temp3 obj = new Temp3();
                  Method method = null;
                  try {
                      method = obj.getClass().getMethod("someMethod");
                  } catch (SecurityException e) {
                  } catch (NoSuchMethodException e) {
                  }
          
                  map.put("someMethod", method);
          
                  try {
                      (map.get("someMethod")).invoke(obj);
                  } catch (IllegalArgumentException e) {
                  } catch (IllegalAccessException e) {
                  } catch (InvocationTargetException e) {
                  }
              }
          
              public void someMethod()    {
                  System.out.println("**************************************");
              } 
          }
          

          【讨论】:

            【解决方案7】:

            是的。虽然,它是“函数”的 java 版本:一个匿名类。

            最好用一个例子来说明:

            interface MyFunction {
                public int calculate(int a, int b);
            }
            
            Map<String, MyFunction> map = new HashMap<String, MyFunction>();
            
            map.put("add", new MyFunction() {
                public int calculate(int a, int b) {
                    return a + b;
                });
            
            map.put("multiply", new MyFunction() {
                public int calculate(int a, int b) {
                    return a * b;
                });
            

            【讨论】:

              猜你喜欢
              • 2022-01-18
              • 2014-12-26
              • 1970-01-01
              • 1970-01-01
              • 2012-03-26
              • 1970-01-01
              • 2013-10-13
              • 2016-01-09
              • 2023-01-12
              相关资源
              最近更新 更多