What is the best way to filter a Java Collection?

后端 未结 27 3424
故里飘歌
故里飘歌 2020-11-21 06:55

I want to filter a java.util.Collection based on a predicate.

27条回答
  •  猫巷女王i
    2020-11-21 07:39

    I needed to filter a list depending on the values already present in the list. For example, remove all values following that is less than the current value. {2 5 3 4 7 5} -> {2 5 7}. Or for example to remove all duplicates {3 5 4 2 3 5 6} -> {3 5 4 2 6}.

    public class Filter {
        public static  void List(List list, Chooser chooser) {
            List toBeRemoved = new ArrayList<>();
            leftloop:
            for (int right = 1; right < list.size(); ++right) {
                for (int left = 0; left < right; ++left) {
                    if (toBeRemoved.contains(left)) {
                        continue;
                    }
                    Keep keep = chooser.choose(list.get(left), list.get(right));
                    switch (keep) {
                        case LEFT:
                            toBeRemoved.add(right);
                            continue leftloop;
                        case RIGHT:
                            toBeRemoved.add(left);
                            break;
                        case NONE:
                            toBeRemoved.add(left);
                            toBeRemoved.add(right);
                            continue leftloop;
                    }
                }
            }
    
            Collections.sort(toBeRemoved, new Comparator() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o2 - o1;
                }
            });
    
            for (int i : toBeRemoved) {
                if (i >= 0 && i < list.size()) {
                    list.remove(i);
                }
            }
        }
    
        public static  void List(List list, Keeper keeper) {
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                if (!keeper.keep(iterator.next())) {
                    iterator.remove();
                }
            }
        }
    
        public interface Keeper {
            boolean keep(E obj);
        }
    
        public interface Chooser {
            Keep choose(E left, E right);
        }
    
        public enum Keep {
            LEFT, RIGHT, BOTH, NONE;
        }
    }
    

    This will bee used like this.

    List names = new ArrayList<>();
    names.add("Anders");
    names.add("Stefan");
    names.add("Anders");
    Filter.List(names, new Filter.Chooser() {
        @Override
        public Filter.Keep choose(String left, String right) {
            return left.equals(right) ? Filter.Keep.LEFT : Filter.Keep.BOTH;
        }
    });
    

提交回复
热议问题