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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With