Predicate 是jakarta commons工具包中一个非常有用的接口, 它主要在对容器类遍历的时候做一些"手脚", 比如根据一定的规则, 逻辑, 对容器对象进行过滤.
在实际开发中我们就碰到一个类似的场景:
一个商品可以根据发往所在地来设置邮费项, 比如一个手机电池从上海发往北京和发往新疆的邮费是不一样的, 于是我们可以设置一些邮费模板项, 但是这些邮费模板项必须是唯一, 比如我设置了北京, 沈阳, 天津三个目的地的邮费都是5块, 接着我又设置了沈阳, 黑龙江的邮费是6块, 则最终得到的邮费项分别是:北京, 天津邮费为5块, 沈阳, 黑龙江为6块, 即能自动针对目的地进行去重处理.去重之后必须遵循后添加的邮费项替换已有的邮费项.
public class RemoveDuplicateDestinationPredicate implements Predicate {
class UniquePostageItem {
String dest;
int mode;
UniquePostageItem(PostageItem item) {
this.dest = item.getDestination();
this.mode = item.getMode();
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
List<PostageItem> completeList = new ArrayList<PostageItem>();
Predicate up = new UniquePredicate();
public boolean evaluate(Object object) {
PostageItem current = (PostageItem) object;
// 初级过滤去重
if (!up.evaluate(new UniquePostageItem(current))) {
return false;
}
// 对item中的每一个destincation进行过滤去重
String[] currentDests = filterDuplicate(current);
// 过滤之后目的地为空的直接排除
String dest = StringUtils.join(currentDests);
if (StringUtils.isEmpty(dest)) {
return false;
}
current.setDestination(dest);
completeList.add(current);
return true;
}
private String[] filterDuplicate(PostageItem current) {
String[] currentDests = current.getDesctinations();
int currentMode = current.getMode();
boolean found = false;
for (int i = 0; i < currentDests.length; i++) {
String currentDest = currentDests[i];
for (PostageItem each : completeList) {
if (each.getMode() == currentMode) {
String[] eachDests = each.getDesctinations();
for (String otherDest : eachDests) {
if (StringUtils.equals(currentDest, otherDest)) {
currentDests[i] = "";
found = true;
break;
}
}
if (found) {
break;
}
}
}
}
return currentDests;
}
}
用法如下:
private static void checkPostageItems(Postage postage, Result<Postage> result) {
List<PostageItem> uniqueItems = new ArrayList<PostageItem>();
for (Iterator<PostageItem> it = removeDuplicateDestinationIterator(items); it.hasNext();) {
final PostageItem item = it.next();
uniqueItems.add(item);
...
}
// 将顺序还原
Collections.sort(uniqueItems, new Comparator<PostageItem>() {
public int compare(PostageItem o1, PostageItem o2) {
return o1.getIndex() - o2.getIndex();
}
});
postage.setPostageItems(uniqueItems);
}
protected static Iterator<PostageItem> removeDuplicateDestinationIterator(final List<PostageItem> items) {
Collections.sort(items, new Comparator<PostageItem>() {
public int compare(PostageItem o1, PostageItem o2) {
return o2.getIndex() - o1.getIndex();
}
});
return new FilterIterator(items.iterator(), new RemoveDuplicateDestinationPredicate());
}