我想获取集合和范围的交集,以便得到一个包含每个不在该范围内的元素的集合。例如,我想从以下代码片段中获取set
和range
的方法:
import com.google.common.collect.*;
TreeSet<Integer> set = Sets.newTreeSet();
Collections.addAll(set, 1,2,3,5,11);
Range<Integer> range = Range.closed(4,10);
并返回一个仅包含
5
的新TreeSet 最佳答案
在这个特定示例中,最好不要使用Range
,而应直接使用set.subSet(4, true, 10, true)
,但是大概您有一个更复杂的用例,并且您的代码是一个简化的示例。
除了您自己处理所有案件外,实际上没有太多选择。问题的一部分是NavigableSet
可以使用任意的Comparator
,但是Range
(故意地)仅适用于值类型的自然排序,因此在Guava中提供一种采用任意Range
和a的方法会有些尴尬。 NavigableSet
并与它们相交。
最通用的解决方案看起来像是...
if (range.hasLowerBound()) {
if (range.hasUpperBound()) {
return set.subSet(
range.lowerEndpoint(),
range.lowerBoundType() == BoundType.CLOSED,
range.upperEndpoint(),
range.upperBoundType() == BoundType.CLOSED);
} else {
return set.tailSet(
range.lowerEndpoint(),
range.lowerBoundType() == BoundType.CLOSED);
}
} else {
if (range.hasUpperBound()) {
return set.headSet(
range.upperEndpoint(),
range.upperBoundType() == BoundType.CLOSED);
} else {
return set;
}
}
就是说,值得一提的是,如果您不关心效率,则可以执行
Iterables.removeIf(set, Predicates.not(range))
或Sets.filter(set, range)
。