题
假设我有一个列表(或集):
List<String> testList = Lists.newArrayList("assocX","srcT","destA","srcX", "don't care Y", "garbage", "srcB");
我想找回一个ImmutableList(集),在自然顺序排序/组方面,其中以“SRC”开头的术语是第一,“ASSOC”第二和“目标”最后。如果一个术语不包含这些那么它应该从结果列表中移除。
因此,结果是在这里 “SRCB”, “SRCT”, “assocX”, “DESTA”。
我想我可以用Iterables.filter或谓词的组合做到这一点,但只是没有看到它。必须有这样做的一个简洁的方式,我认为。
编辑:代替列表的一组工程,以及
解决方案
只要这三个前缀是您所关心的唯一的事情,我建议是这样的:
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)
)
);
这个解决方案绝对不会,如果你开始增加更多的前缀过滤掉或排序,因为你必须不断地更新两个过滤器和每个前缀的体重秤出令人难以置信的好。
其他提示
看一看此谷歌集合示例。
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();
虽然这,诚然,返回一个集合。
我认为你必须首先使用谓词来消除你不想要的元素,以及实施的比较和排序列表中。
一般是不好的设计以这样的整理明显不同的数据。在你的情况,当你说“assocX”,“ASSOC”具有“X”独立的意义,但你把它们合并在一起。
所以我建议有两个字段设计类。然后你就可以在第二的第一个字段创建一个排序,另一个,并结合他们(例如订货#化合物())。与一个toString()方法不合并这些字段为一个字符串。作为奖励,这可以极大地通过共用减少内存使用。
所以,你会被这种排序对象的列表,如果你想打印出来,你只需调用toString()在他们身上。
不隶属于 StackOverflow