使用Google集合过滤和排序列表

假设我有一个列表(或Set):

List 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 filter = new Predicate() { @Override public boolean apply(String input) { return input.startsWith("src") || input.startsWith("assoc") || input.startsWith("dest"); } }; Function assignWeights = new Function() { @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 sortedFiltered = ImmutableList.copyOf( Ordering.natural().onResultOf(assignWeights).sortedCopy( Iterables.filter(testList, filter) ) ); 

如果您开始添加更多前缀来过滤或排序,这个解决方案绝对不会非常好地扩展,因为您必须不断更新filter和每个前缀的权重。

请查看此Googlecollections集示例 。

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

诚然,虽然这回归了一套。

我想你将首先使用谓词来消除你不想要的元素,并实现比较器并对列表进行排序。

通常,如此清晰地整理不同的数据是不好的设计。 在您的情况下,当您说“assocX”时,“assoc”与“X”具有单独的含义,但您将它们合并在一起。

所以我建议设计一个有两个字段的类。 然后,您可以在第一个字段上创建排序,在第二个字段上创建另一个排序,并将它们组合起来(例如,订购#compound())。 使用toString()方法将这些字段合并为一个字符串。 作为奖励,这可以通过共享大大减少内存使用量。

所以你要排序这些对象的列表,如果你想打印它们,你只需要调用它们上的toString()。