[英]filter and sort list using google collections
假設我有一個列表(或Set):
List<String> testList = Lists.newArrayList("assocX","srcT","destA","srcX", "don't care Y", "garbage", "srcB");
我想找回一個ImmutableList(Set),它按照自然順序對術語進行排序/分組,其中以“src”開頭的術語是第一個,“assoc”第二個和“dest”最后一個。 如果術語不包含那些術語,則應從結果列表中刪除它。
因此,這里的結果是“srcB”,“srcT”,“assocX”,“destA”。
我想我可以通過Iterables.filter或Predicates的某些組合來做到這一點,但只是沒有看到它。 我認為必須有一種簡潔的方法。
編輯:代替列表的集合也可以。
只要這三個前綴是你唯一關心的事情,我建議這樣的事情:
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)
)
);
如果您開始添加更多前綴來過濾或排序,這個解決方案絕對不會非常好地擴展,因為您必須不斷更新過濾器和每個前綴的權重。
請查看此Google收藏集示例 。
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();
盡管如此,誠然,這會返回一個Set。
我認為你將首先使用謂詞來消除你不想要的元素,並實現比較器並對列表進行排序。
通常,如此清晰地整理不同的數據是不好的設計。 在您的情況下,當您說“assocX”時,“assoc”與“X”具有單獨的含義,但您將它們合並在一起。
所以我建議設計一個有兩個字段的類。 然后,您可以在第一個字段上創建排序,在第二個字段上創建另一個排序,並將它們組合起來(例如,訂購#compound())。 與沒有這些字段合並為一個字符串toString()方法。 作為獎勵,這可以通過共享大大減少內存使用。
所以你要排序這些對象的列表,如果你想打印它們,你只需要調用它們上的toString()。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.