Я думаю TreeRangeSet
реализации глючит.
RangeSet Guava javadoc определяет следующий контракт:
Реализации, которые выбирают для поддержки оных (Range) операции должны игнорировать> пустые диапазоны и сливаться подключенные диапазоны. Например:
RangeSet<Integer> rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
rangeSet.add(Range.closedOpen(11, 15)); // disconnected range; {[1, 10], [11, 15)}
rangeSet.add(Range.closedOpen(15, 20)); // connected range; {[1, 10], [11, 20)}
rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}
rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}
Фактически реализация TreeRangeSet
выполняет следующие действия (обратите внимание на разницу в отношении [11, 20)
/[11, 15), (15, 20)
:
rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
rangeSet.add(Range.closedOpen(11, 15)); // {[1, 10], [11, 15)}
rangeSet.add(Range.open(15, 20)); // disconnected range; {[1, 10], [11, 15), (15, 20)}
rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 15), (15, 20)}
rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 15), (15, 20)}}
Существует несколько случаев:
[1, 10] + [11, 15)
не соединены, но они связаны ...
[10, 15) + (15, 20)
не объединены, это нормально, так как они отсоединены. Однако комментарии в фрагменте кода javadoc говорят, что он должен быть объединен ...
[10, 10] + [11, 20)
не объединены, но они связаны ...
Я думаю, что единственный способ, которым Вы можете сделать это, пока она не будет исправлена, чтобы добавить «closedOpen» диапазоны, с верхней границей множества к вашему фактическому UpperBound + 1:
Вы можете сделать что-либо @ путь LouisWasserman», или:
rangeSet.add(Range.closedOpen(1, 11)); // {[1, 11)}
rangeSet.add(Range.closedOpen(11, 21)); // {[1, 21)}
Вы также можете создать метод, чтобы "автоматизировать" трюк UpperBound, например:
public void addRangeToSet(int lowerBound, int upperBound, RangeSet<Integer> set){
set.add(Range.closedOpen(lowerBound, upperBound + 1));
}
...
addRangeToSet(1, 10, set); // {[1, 11)}
addRangeToSet(11, 20, set); // {[1, 21)}
rangeSet.add(Range.closedOpen(1, 10)); // {[1, 10)}
rangeSet.add(Range.closedOpen(11, 20)); // {[1, 21)}
EDIT
isConnected
method JavaDoc утверждает, что:
Обратите внимание, что некоторые дискретные диапазоны не считаются связно, даже если нет никаких элементов "между ними." Например, [3, 5] не считается подключенным к [6, 10]. В этих случаях может быть желательно, чтобы оба входных диапазона были предварительно обработаны каноническим (DiscreteDomain) перед тестированием на связность.
Так что "лучший" подход, как представляется, одним из @ LouisWesserman в:
rangeSet.add(Range.closed(1, 10).canonical(DiscreteDomain.integers()); // {[1, 11)}
rangeSet.add(Range.closed(11, 20).canonical(DiscreteDomain.integers()); // {[1, 21)}
Не могли бы вы привести пример, где это имеет значение? –
Это важно с датами, но я хотел, чтобы это было просто. Если вы работаете с 1 по 11 января и с 12 по 20 января, вы фактически работаете с 1 по 20-е. Мне нужно сохранить информацию в одной строке в моем приложении. –