【问题标题】:Java - How to compare Guava Ranges?Java - 如何比较番石榴范围?
【发布时间】:2018-10-30 14:11:12
【问题描述】:

我决定创建一个地图来存储指标名称和代表每个指标的生存期的范围。起初我使用TreeRangeMap 来存储 Ranges,但由于每个 Metric 包含一个 Range,我切换到 Ranges,如下所示。

我的目标是在收到来自外部 API 的度量标准 Range 时,将最新时间范围保留在 DEFAULT_METRICS_MAP 中。 当我有一个代表 Ranges 的 TreeRangeMap 时,比较它们很容易。我向 TreeRangeMap 添加了新指标,然后得到了这样的最大范围:

private static Optional<Range<Long>> maxRange(TreeRangeSet<Long> rangeSet) {
    Set<Range<Long>> ranges = rangeSet.asRanges();
    return ranges.stream().max(Comparator.comparing(Range::upperEndpoint));
} 

如果没有将 Ranges 包装到 TreeRangeMap 中,比较 Ranges 的正确方法是什么?

public static final Map<String, Range<Long>> DEFAULT_METRICS_MAP;
static {
        Map<String, Range<Long>> theMap = new HashMap<>();
        theMap.put("Metric1", Range.closed(Long.MIN_VALUE, Long.MAX_VALUE));
        theMap.put("Metric2", Range.closed(10L, 20L));
        theMap.put("Metric3", Range.closed(30L, 50L));
        METRICS_MAP = Collections.unmodifiableMap(theMap);
    }

【问题讨论】:

  • 你期望的输出是什么?

标签: java collections java-8 guava comparator


【解决方案1】:

首先,在这种特殊情况下避免使用TreeRangeMap/TreeRangeSet 是一个正确的决定。据我了解(如果我错了,请纠正我),您不需要保留所有指标的所有范围。您需要的是每个指标在每个时刻的最新范围。 理想情况下,您希望有一种非常快速的检索方法,例如:

Range<Long> range = getRange(metric);

最有效的方法是在收到Range 对象时进行比较:

public void setRange(String metric, Range<Long> newRange) {
    Range<Long> oldRange = metricRanges.get(metric);
    if (comparator.compare(newRange, oldRange) > 0) {
        metricRanges.put(metric, newRange);
    }
}

这里是完整的例子:

// Better keep this map encapsulated
private final Map<String, Range<Long>> metricRanges = new HashMap<>();

private final Comparator<Range<Long>> comparator = 
                   Comparator.nullsFirst(Comparator.comparing(Range::upperEndpoint));

static {
    // Fill in your map with default ranges
}

public void setRange(String metric, Range<Long> newRange) {
    Range<Long> oldRange = metricRanges.get(metric);
    if (comparator.compare(newRange, oldRange) > 0) {
        metricRanges.put(metric, newRange);
    }
}

public Range<Long> getRange(String metric) {
    return metricRanges.get(metric);
}

如果你还需要Optional:

public Optional<Range<Long>> getRange(String metric) {
    return Optional.of(metricRanges.get(metric));
}

【讨论】:

    猜你喜欢
    • 2016-06-24
    • 2013-08-07
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多