我想在列表中的对象的属性上实现搜索。
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
}
}
}
答案 0 :(得分:0)
我怀疑你可以用这个问题进行bin搜索。如果要进行二进制搜索,则必须按给定的propertyName对集合中的元素进行排序。如果不是,则必须先对其进行排序(例如,使用比较器)。因此,您要将O(n)
问题更改为O(nlgn)
。
我能想到的是:java reflection 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)
来自guava的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.Predicate)
答案 1 :(得分:0)
正如其他人所说,如果不先对列表进行排序,就不能使用二进制搜索,所以我不会考虑到这一点。
使用Google的Guava libraries我可以很好地解决这个问题而不需要反思。
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));
}
});
}
此功能有三个参数。
为了在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.GetName
等后,使用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");
}