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()); }