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.
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.