Reputation: 4130
I have the following method to use a Predicate to filter a collection, throwing out any members where propertyName isn't in a given list of allowed values. It uses Common-BeanUtils to extract a value from the object, and that value has to be a 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);
}
Unfortunately, my test fails utterly.
@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);
}
Am I making an incredibly stupid mistake here?
Update: working code is below.
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));
}
Upvotes: 1
Views: 481
Reputation: 691765
Yes, you're doing an incredibly stupid mistake ;-)
You're not returning the filtered list. filter()
doesn't modify the given list. It returns a filtered Iterable.
Also, allowedValues should be a HashSet rather than a List. That would make your filter more efficient. HashSet.contains()
runs in constant time, whereas List.contains()
is O(n)
.
Upvotes: 5