filter and sort list using google collections

前端 未结 4 893
被撕碎了的回忆
被撕碎了的回忆 2020-12-23 12:08

Suppose I have a list (or Set):

List testList = Lists.newArrayList(\"assocX\",\"srcT\",\"destA\",\"srcX\", \"don\'t care Y\", \"garbage\", \"sr         


        
相关标签:
4条回答
  • 2020-12-23 12:32

    I think you'll have first to use the predicate to eliminate elements you don't want, and the implement a Comparator and sort your list.

    0 讨论(0)
  • 2020-12-23 12:48

    Usually it's bad design to collate clearly distinct data like this. In your case, when you say "assocX", "assoc" has a separate meaning from "X", yet you merge them together.

    So I would suggest designing a class with two fields. Then you can create an ordering on the first field, another on the second, and combine them (e.g. Ordering#compound()). With a toString() method that does merge these fields into a string. As a bonus, this may greatly reduce memory usage via sharing.

    So you would be sorting a list of such objects, and if you wanted to print them, you would just call toString() on them.

    0 讨论(0)
  • 2020-12-23 12:50

    As long as those three prefixes are the only things you care about, I'd suggest something like this:

        Predicate<String> filter = new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                return input.startsWith("src") || input.startsWith("assoc") || input.startsWith("dest");
            }
        };
    
        Function<String, Integer> assignWeights = new Function<String, Integer>() {
            @Override
            public Integer apply(String from) {
                if (from.startsWith("src")) {
                    return 0;
                } else if (from.startsWith("assoc")) {
                    return 1;
                } else if (from.startsWith("dest")) {
                    return 2;
                } else {
                    /* Shouldn't be possible but have to do something */
                    throw new IllegalArgrumentException(from + " is not a valid argument");
                }
            }
        };
    
        ImmutableList<String> sortedFiltered = ImmutableList.copyOf(
                Ordering.natural().onResultOf(assignWeights).sortedCopy(
                        Iterables.filter(testList, filter)
                )
        );
    

    This solution definitely wouldn't scale out incredibly well if you start adding more prefixes to filter out or sort by, since you'd have to continually update both the filter and the weight of each prefix.

    0 讨论(0)
  • 2020-12-23 12:54

    Have a look at This Google Collections example.

    Function<Fruit, String> getNameFunction = new Function<Fruit, String>() {
        public String apply(Fruit from) {
            return from.getName();
        }
    };
    
    Ordering<Fruit> nameOrdering = Ordering.natural().onResultOf(getNameFunction);
    
    ImmutableSortedSet<Fruit> sortedFruits = ImmutableSortedSet.orderedBy(
        nameOrdering).addAll(fruits).build();
    

    Though this, admittedly, returns a Set.

    0 讨论(0)
提交回复
热议问题