3

我想取集合和范围的交集,以便得到一个集合,其中包含不在范围内的每个元素。例如,我想要一种从以下代码片段中获取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);

并返回一个新的 TreeSet 只包含5

4

1 回答 1

10

在这个特定的例子中,你最好不要使用Range,而是set.subSet(4, true, 10, true)直接使用,但可能你有一个更复杂的用例,你的代码是一个简化的例子。

除了自己处理所有案件之外,真的没有太多选择。部分问题是 aNavigableSet可以使用任意Comparator,但Range(故意)仅适用于值类型的自然顺序,因此在 Guava 中提供一个采用任意Range和 aNavigableSet并与它们相交的方法会有些尴尬。

最通用的解决方案看起来像......

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))or Sets.filter(set, range)

于 2013-01-28T22:13:47.527 回答