Java - Как сравнить диапазоны гуавы? - PullRequest
0 голосов
/ 30 октября 2018

Я решил создать карту для хранения названий метрик и диапазонов, представляющих периоды жизни для каждой метрики. Сначала я использовал TreeRangeMap для хранения диапазонов, но так как каждая метрика содержит один диапазон, я переключился на диапазоны, как показано ниже.

Моя цель - сохранить последний временной диапазон в DEFAULT_METRICS_MAP, когда я получу Range для метрики от внешнего API. Когда у меня был 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));
} 

Каков будет правильный способ сравнения диапазонов, если они не заключены в TreeRangeMap?

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);
    }

1 Ответ

0 голосов
/ 31 октября 2018

Прежде всего, это было правильное решение избегать использования 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));
}
...