0

我想对列表中的对象的属性进行搜索。

class Test
{
    int id;
    int name;
    int address;

    //Setter and getter method of properties
}

public List<Test> searchData(String serachText, String propertyName)
{
    //Write code to search data from list
}

输入参数:

searchData("val1", "name");
searchData("val2", ("address");

我想去,Collections.binarySearch但如何进行dynamic comparator我不知道的搜索。

实现这种功能的正确方法是什么?

是否可以使用Collections.binarySearch或任何其他具有良好代码质量和更好性能的好方法来实现它?

编辑

public List<Test> searchData(String serachText, String propertyName)
{
List<Test> finalSearch=new ArrayList<Test>();
//Write code to search data
for(Test test:testList)
{
  if(propertyName.equals("name"))
{
    if(serachText.equals(test.getName())
    {
       finalSearch.add(test);
     }
///Same code for others
}
}
}
4

2 回答 2

0

我怀疑你可以对这个问题进行 bin 搜索。如果要进行二分搜索,则集合中的元素必须按给定的 propertyName 排序。如果不是,则必须先对其进行排序(例如使用比较器)。因此,您将O(n)问题更改为O(nlgn).

我能想到的是:java反射API....也就是说,在你的searchData方法中,通过给定的属性名称构建getter方法(java.lang.reflect.Method)。并调用(method.invoke() http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object , java.lang.Object...) )获取属性值。并进行过滤。

你可以自己实现它,如果你不介意使用库,你可以看看 apache beanUtils: (getProperty() 方法)

http://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtilsBean.html#getProperty(java.lang.Object , java.lang.String)

还有Iterables.filter()番石榴的方法:

http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#filter(java.lang.Iterable , com.google.common.base.谓词)

于 2013-10-02T12:49:37.497 回答
0

正如其他人所说,如果不先对列表进行排序,就不能使用二进制搜索,所以我不会考虑到这一点。

我使用 Google 的Guava 库对这个问题有一个优雅的解决方案,而无需借助反射。

public static <T, V> Collection<T> filter(List<T> source, final Function<? super T, V> function, final V value) {
    return Collections2.filter(source, new Predicate<T>() {
        @Override
        public boolean apply(T input) {
            return value.equals(function.apply(input));
        }
    });
}

这个函数接受三个参数。

  1. 您要过滤的列表。
  2. 一个函数,它接受列表的一个元素,并返回要过滤的属性的值
  3. 您希望该属性具有的值

为了在 Java 8 之前使用它,您可以编写如下内容:

static class Test {
    int id;
    String name;
    String address;

    public Test(int id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    //Setter and getter method of properties...

    public static final Function<Test, Integer> GetId = new Function<Test, Integer>() {
        @Override
        public Integer apply(Test input) {
            return input.id;
        }
    };
    public static final Function<Test, String> GetName = new Function<Test, String>() {
        @Override
        public String apply(Test input) {
            return input.name;
        }
    };

}

一旦定义了Test.GetId, Test.GetNameetc ,使用filter就简单明了:

public static void main(String[] args) {
    List<Test> t = Arrays.asList(new Test(1, "A", "B"), new Test(2, "C", "D"));
    Collection<Test> f1 = filter(t, Test.GetId, 2);
    Collection<Test> f2 = filter(t, Test.GetName, "A");
}
于 2013-10-02T13:05:07.150 回答