Разница между оцененным размером и getExactSizeIfKnown в Spliterator - PullRequest
5 голосов
/ 30 марта 2019

Я пытаюсь понять особенности Spliterator и наткнулся на эти 2 метода estimatedSize и getExactSizeIfKnown. Я мог бы понять, что такое estimatedSize, но не уверен, что именно делает getExactSizeIfKnown.Может кто-нибудь, пожалуйста, приведите пример, объясняющий разницу между ними.

РЕДАКТИРОВАТЬ: я попробовал следующий пример, в котором оба они одинаковы.В каких случаях они будут другими?

public static void main(String[] args) {
        List<Integer> l = new ArrayList<>();
        l.add(1);
        l.add(2);
        l.add(3);
        Spliterator<Integer> s= (Spliterator<Integer>) l.spliterator();
    Spliterator<Integer> s1=s.trySplit();
    while(s.tryAdvance(n -> {System.out.print(n+" ");System.out.println("estimateSize "+s.estimateSize()+" getexactsizeifknown "+s.getExactSizeIfKnown());})); 

1 Ответ

5 голосов
/ 30 марта 2019

Метод estimateSize:

Возвращает оценку количества элементов, которые могут встретиться при прохождении forEachRemaining(java.util.function.Consumer<? super T>), иливозвращает Long.MAX_VALUE, если оно бесконечно, неизвестно или слишком дорого для вычисления.

Если этот Spliterator равен SIZED и еще не был частично пройден или разделен,или этот Spliterator является SUBSIZED и еще не был частично пройден, эта оценка должна быть точным подсчетом элементов, которые могут встретиться при полном обходе.В противном случае эта оценка может быть произвольно неточной, но должна уменьшаться, как указано для вызовов trySplit().

API Примечание:

Даженеточная оценка часто бывает полезной и недорогой для вычисления.Например, подсплитератор приблизительно сбалансированного двоичного дерева может возвращать значение, которое оценивает число элементов, равное половине от его родительского элемента;если корневой Spliterator не поддерживает точный счет, он может оценить размер как степень двух, соответствующую его максимальной глубине.

И метод getExactSizeIfKnown является:

Удобный метод, который возвращает estimateSize(), если этот Spliterator равен SIZED, иначе -1.

Требования к реализации:

Реализация по умолчанию возвращает результат estimateSize(), если Spliterator сообщает характеристику SIZED, и -1 в противном случае.

Обаиз этих методов ссылка SIZED, которая представляет собой:

Характеристическое значение, означающее, что значение, возвращаемое из estimateSize() до обхода или разделения, представляет конечный размер, который вотсутствие структурной модификации источника представляет точный подсчет количества элементов, которые могут встретиться при полном обходе.

Примечание API:

Большинство Spliterators для коллекций, что соver все элементы Collection сообщают об этой характеристике.Суб-сплитераторы, такие как для HashSet, которые охватывают поднабор элементов и приблизительный их размер, о котором сообщают, не делают.

На основании всего этого,два метода будут когда-либо возвращать разные значения, только если Spliterator не имеет характеристики SIZED .


В вашем примере источником Spliterator являетсяArrayList.Если мы посмотрим на документацию ArrayList.spliterator():

Создает с поздним связыванием и отказоустойчивым Spliterator по элементам в этом списке.

Spliterator сообщает Spliterator.SIZED, Spliterator.SUBSIZED и Spliterator.ORDERED.Переопределяющие реализации должны документировать отчеты о дополнительных значениях признаков.

Из-за характеристики SUBSIZED, Spliterator создается из ArrayList, включая значения, полученные в результате trySplit - никогда не будет estimateSize и getExactSizeIfKnown возвращать разные значения.

...