Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter and sort list using google collections

Suppose I have a list (or Set):

List<String> testList = Lists.newArrayList("assocX","srcT","destA","srcX", "don't care Y", "garbage", "srcB"); 

I would like to get back an ImmutableList(Set) that sorts/groups terms in natural order where terms that begin with "src" are first, "assoc" second and "dest" last. If a term does not contain those then it should be removed from the resulting list.

Therefore the result here is "srcB", "srcT", "assocX", "destA".

I think I can do this with some combination of Iterables.filter or Predicates but just not seeing it. There must be a succinct way of doing it I think.

EDIT: A set in place of a list works as well.

like image 774
harschware Avatar asked Feb 22 '10 17:02

harschware


People also ask

How can you sort the elements of a list collection?

We can use Collections. sort() method to sort a list in the natural ascending order. All the elements in the list must implement Comparable interface, otherwise IllegalArgumentException is thrown.


1 Answers

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.

like image 144
Paul Blessing Avatar answered Sep 21 '22 22:09

Paul Blessing