番石榴 - 如何根据谓词从列表中删除,跟踪删除的内容?

2022-09-02 23:53:14

我有一个要过滤的,还有各种番石榴要过滤。此列表将只有 50-100 个元素。ArrayListPredicate

我计划依次使用每个谓词。它可能不是最大的效率,但没关系(至少对RandomAccess列表进行了一些优化)Iterables.removeIfremoveIf

对于调试,我想简明扼要地记录每个谓词的作用。例如:

Pred0 removed [a, c, g]
Pred1 removed []
Pred2 removed [b, f]

有一些明显的黑客解决方案,但你认为什么是最干净的?

对于奖励积分,它也应该相当有效。;)


答案 1

我会在谓词代码中捕获已删除的元素。

List<String> removedElements = Lists.newArrayList();
final Iterables.removeIf(list, new Predicate<String>() {
    @Override
    public boolean apply(String input) {
        if ("a".equals(input)) {
            removedElements.add(input);
            return true;
        }
        return false;
    }
}); 

答案 2

这可能是使用循环最简单的情况。

List<MyType> list =
Predicate<MyType>[] predicates =
Map<Predicate, List<MyType>> removed = 
      new LinkedHashMap<Predicate, List<MyType>>();
for(Iterator<MyType> iter=list.iterator();list.hasNext();) {
   MyType mt = iter.next();
   for(Predicate<MyType> pred: predicates) 
       if(pred.apply(mt)) {
          List<MyType> mts = removed.get(pred);
          if(mts == null)
              removed.put(pred, mts = new ArrayList<MyType>());
          mts.add(mt);
          iter.remove();
          break;
       }
 }