You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Guava RangeSet的difference操作中获取闭区间结果?

如何将Guava RangeSet的difference结果转为闭区间?

Guava的RangeSet在处理区间运算时,为了保证区间之间无重叠且无缝衔接,默认会输出半开区间(比如[1..3)或者(6..10])。要把difference操作的结果转成你需要的闭区间形式,我们可以手动遍历结果中的每个区间,根据边界类型调整端点,转换成完全闭合的区间。

实现代码示例

import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.Range;
import java.util.ArrayList;
import java.util.List;

public class RangeSetExample {
    public static void main(String[] args) {
        ImmutableRangeSet<Integer> rangeSet1 = ImmutableRangeSet.of(Range.closed(1, 10));
        ImmutableRangeSet<Integer> rangeSet2 = ImmutableRangeSet.of(Range.closed(3, 6));
        ImmutableRangeSet<Integer> differenceResult = rangeSet1.difference(rangeSet2);

        // 将半开区间转换为闭区间集合
        List<Range<Integer>> closedRanges = new ArrayList<>();
        for (Range<Integer> range : differenceResult.asRanges()) {
            if (range.hasLowerBound() && range.hasUpperBound()) {
                Range.BoundType lowerType = range.lowerBoundType();
                Range.BoundType upperType = range.upperBoundType();
                int lower = range.lowerEndpoint();
                int upper = range.upperEndpoint();

                if (lowerType == Range.BoundType.CLOSED && upperType == Range.BoundType.OPEN) {
                    // [a..b) → [a..b-1]
                    closedRanges.add(Range.closed(lower, upper - 1));
                } else if (lowerType == Range.BoundType.OPEN && upperType == Range.BoundType.CLOSED) {
                    // (a..b] → [a+1..b]
                    closedRanges.add(Range.closed(lower + 1, upper));
                } else {
                    // 已经是闭区间或其他类型,直接保留
                    closedRanges.add(range);
                }
            }
        }

        // 转换为ImmutableRangeSet(按需使用)
        ImmutableRangeSet<Integer> closedResult = ImmutableRangeSet.copyOf(closedRanges);
        System.out.println(closedResult); // 输出:[[1..2], [7..10]]
    }
}

逻辑说明

  • 遍历difference返回的每个区间,通过lowerBoundType()和upperBoundType()判断区间的边界类型
  • 针对离散的Integer类型,左闭右开区间[a..b)等价于包含从a到b-1的所有整数,因此可以直接调整为闭区间[a, b-1]
  • 左开右闭区间(a..b]等价于包含从a+1到b的所有整数,调整为闭区间[a+1, b]
  • 这种转换仅适用于离散数值类型(如Integer、Long),如果是连续类型(如Double),无法通过简单的端点加减实现等价的闭区间转换

内容的提问来源于stack exchange,提问作者Ihor Rybak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:01:33