我有以下方法使用Predicate过滤集合,抛出propertyName不在给定的允许值列表中的任何成员.它使用Common-BeanUtils从对象中提取值,该值必须是String:
public static <T> void filterListByStringPropertyWithAllowableValues(List<T> listToFilter,
final String propertyName,
final List<String> allowedValues) {
Predicate<T> allowedValuesPredicate = new Predicate<T>() {
@Override
public boolean apply(T arg0) {
String value;
boolean result = false;
try {
value = BeanUtils.getProperty(arg0, propertyName);
System.out.println(value);
result = allowedValues.contains(value);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return result;
}
};
Iterables.filter(listToFilter, allowedValuesPredicate);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我的测试彻底失败了.
@Test
public void testfilterListByStringPropertyWithAllowableValues() throws Exception {
TestClass item1 = new TestClass("value1","whatever1");
TestClass item2 = new TestClass("value2","whatever2");
TestClass item3 = new TestClass("value3","whatever3");
List<TestClass> initialList = Lists.newArrayList(item1, item2, item3);
MyCollectionUtils.filterListByStringPropertyWithAllowableValues(initialList, "importantField",
Lists.newArrayList("value1","value2"), 3);
assertTrue("Collection size should be 2. Actual: " + initialList.size(), initialList.size() == 2);
}
Run Code Online (Sandbox Code Playgroud)
我在这里犯了一个令人难以置信的愚蠢错误吗?
更新:工作代码如下.
public static <T> List<T> filterListByStringPropertyWithAllowableValues(List<T> listToFilter,
final String propertyName,
final Set<String> allowedValues) {
Predicate<T> allowedValuesPredicate = new Predicate<T>() {
@Override
public boolean apply(T arg0) {
String value;
boolean result = false;
try {
value = BeanUtils.getProperty(arg0, propertyName);
System.out.println(value);
result = allowedValues.contains(value);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return result;
}
};
return Lists.newArrayList(Iterables.filter(listToFilter, allowedValuesPredicate));
}
Run Code Online (Sandbox Code Playgroud)
是的,你做了一个令人难以置信的愚蠢的错误;-)
您没有返回已过滤的列表.filter()不会修改给定的列表.它返回一个过滤的Iterable.
另外,allowedValues应该是HashSet而不是List.这将使您的过滤器更有效.HashSet.contains()运行在固定的时间,而List.contains()为O(n).