Java - 如何比较番石榴范围?
Java - How to compare Guava Ranges?
我决定创建一个 Map 来存储指标名称和代表每个指标生命周期的范围。起初我使用 TreeRangeMap
来存储范围,但由于每个指标都包含一个范围,所以我切换到如下所示的范围。
我的目标是当我从外部 API 收到指标的 Range
时,将最新时间范围保持在 DEFAULT_METRICS_MAP 内。
当我有一个代表范围的 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);
}
首先,在这种特殊情况下避免使用 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));
}
我决定创建一个 Map 来存储指标名称和代表每个指标生命周期的范围。起初我使用 TreeRangeMap
来存储范围,但由于每个指标都包含一个范围,所以我切换到如下所示的范围。
我的目标是当我从外部 API 收到指标的 Range
时,将最新时间范围保持在 DEFAULT_METRICS_MAP 内。
当我有一个代表范围的 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);
}
首先,在这种特殊情况下避免使用 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));
}