二进制搜索方法数组Java

时间:2013-02-20 14:58:05

标签: java reflection binary-search comparator comparable

我正在尝试有效地搜索天气,子类实现了一个名为_szMethodName的字符串中的名称的方法。我可以通过执行Method[] _arrClassMethodsList = class.getMethods();来获取子类实现的所有方法的数组。然后,我可以将方法的名称与我要查找的函数的stringName进行比较,以确定天气与否实现该特定方法。目前我在for循环中工作,但随着子类的增长,这会变慢。

For Loop implementation:

for (Method method : class.getMethods()){
       if(method.getName().equals(_szMethodName)){
          //method exists in subclass
          break;
      }
}

来自class.getMethods()的方法数组按字母顺序排序。(仅限Java> = 7)。我希望通过在数组上使用二进制搜索或其他优化而不是使用for循环来利用它。但是,我还没有弄清楚如何在阵列上实现Java的二进制搜索功能。我曾尝试使用比较器或可比较但尚未取得成功。我最近的比较器实现如下,但有一些我尚未解决的错误。

目前使用比较器的尝试:

Comparator<Method> c = new Comparator <Method>() {
    public int compare(Method method, String string) {
        return method.getName().compareTo(string);
    }
};

Method[] _arrClassMethodsList = class.getMethods();
int index = Arrays.binarySearch(_arrClassMethodsList, _szMethodName, c);

任何有关如何使这项工作的帮助或示例将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:5)

为什么不使用方法http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29直接获取方法(如果可用)并让JVM有效地为您完成工作?

BTW,getMethods的文档说:“返回的数组中的元素是 未排序 不按任何特定顺序 ”。二进制搜索需要排序数据。这意味着您首先需要对数组进行排序。

注意:您应该查看可能符合您预期的方法getMatchingAccessibleMethod

答案 1 :(得分:0)

看起来唯一真正的方法是重新实现二进制搜索,在搜索过程中拉出方法名称。我的最终实施如下。谢谢各位的帮助。

public final Method NOT_FOUND = null;
private Method findMethodInDelegateClassWithParameters (String _szMethodName)
{
    @SuppressWarnings("rawtypes")
    Class _cDelegateClass = m_oDelegate.getClass();

    //Get and sort array for binary search if not done, ensure methods are alphabetical before Java 7 
    if (_arrSortedMethods==null){
        _arrSortedMethods = _cDelegateClass.getMethods();   
        Arrays.sort(_arrSortedMethods, new Comparator<Method>() {
               public int compare(Method m1, Method m2) {
                   return m1.getName().compareTo(m2.getName());
               }
        });
    }

    return binarySearchForMethodNamed(_arrSortedMethods, _szMethodName);
}

public Method binarySearchForMethodNamed(Method[] _arrMethods, String _szMethodName) {
    int left = 0;
    int right = _arrMethods.length - 1;
    return binarySearchMethods(_arrMethods, _szMethodName, left, right);
    }

private Method binarySearchMethods(Method[] _arrMethods, String _szMethodName, int left, int right) {
    if (right < left) {
            return NOT_FOUND;
    }

    int mid = (left + right) >>> 1;
    String _szArrayMethodName = _arrMethods[mid].getName();
    if (_szMethodName.compareTo(_szArrayMethodName)>0) {
            return binarySearchMethods(_arrMethods, _szMethodName, mid + 1, right);
    } else if (_szMethodName.compareTo(_szArrayMethodName)<0) {
            return binarySearchMethods(_arrMethods, _szMethodName, left, mid - 1);
    } else {
            return _arrMethods[mid];
    }               
}