2017-06-02 15 views
5

https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.htmlSpliterator - wielkości vs subsized flagi

SKLEJONY charakterystyczną wartość co oznacza, że ​​zwrócona wartość estimateSize() przed przechodzenie lub rozszczepianie reprezentuje skończony rozmiar, że w przypadku braku zmiany źródła strukturalnego reprezentuje dokładną liczbę elementów, które zostałyby napotkane podczas pełnego przejścia.

SUBSIZED Wartość charakterystyczna oznaczająca, że ​​wszystkie Spliteratory wynikające z trySplit() będą miały zarówno SIZED, jak i SUBSIZED.

  1. Czy istnieje sytuacja, gdy flaga jest na SKLEJONY ale SUBSIZED flaga jest off?
  2. Czy jest sytuacja, gdy flaga SUBSIZED jest włączona, ale flaga SIZED jest wyłączona?

Odpowiedz

7

Typowym przykładem Spliterator że jest SIZED ale nie SUBSIZED, to Spliterator utworzone z HashMap. Zachowuje zakres w obrębie wewnętrznej tablicy wpisów, niektóre z tych wpisów tablicy są równe null, ponieważ pojemność jest większa niż rzeczywisty rozmiar. Dokładna dystrybucja wpisów do pominięcia zależy od kodów skrótów zawartych w kluczach.

Tak więc Spliterator najpierw zna swój (całkowity) rozmiar, ale przy podziale zakresu nie wie, ile elementów znajduje się w każdym zakresie. Im więcej elementów ma, tym większe prawdopodobieństwo zgrubnie zrównowaŜonego podziału, więc ta strategia jest rozsądna, ale dokładne subsizesy nie są znane i wymagałoby to iteracji w tablicy, aby się dowiedzieć.

Zgłaszanie cechy SUBSIZED bez SIZED nie ma sensu i jest, o ile rozumiem, nieważne.

+0

W HashMap, jeśli nie wiem, ile wartości jest równe zeru, jak flaga SIZED jest włączona? –

+3

'HashMap' zawsze zachowuje swój rozmiar, jest to prosta zmienna' int'. Więc wie * ile jest wartości * 'null'; jest to różnica między pojemnością (długość tablicy) i "wielkością", ale nie wiadomo, w jaki sposób są dystrybuowane przez macierz. – Holger

+2

@Holger, jeśli jest to "wewnętrzna tablica, która jest podzielona, ​​podejrzewam, że kolizje powodują, że zasób jest nieznany, prawda? Pierwszy zasobnik może mieć 3 wpisy, podczas gdy pozostałe mają na przykład 0 lub jeden. Czy rozumiem to poprawnie? –

2

Trochę za późno, ale wciąż ... Zaskoczyło mnie to już jakiś czas temu. będę wyliczać te, które ja znam:

HashMap (jak wspomniano powyżej) i jako taki IdentityHashMap, LinkedHashMap i TreeMap.

Rzeczą godną uwagi jest to, że ConcurrentHashMap jest nie występuje na liście, ponieważ umożliwia równoczesne aktualizacje, więc rozmiar jest rzeczywiście wielkość w momencie wywołania. W rzeczywistości CHM nawet nie zgłasza SIZED oczywiście.

Następnie są te, które odnoszą się do Map, jak HashSet i TreeSet, ponieważ wewnętrznie nadal są to Mapy.

A potem jest jeden, który jest nieco un-tu spodziewać w obliczu BitSet dla których BitSetSpliterator#characteristics wygląda następująco:

@Override 
    public int characteristics() { 
     // Only sized when root and not split 
     return (root ? Spliterator.SIZED : 0) | 
      Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED; 
    } 

To może wyglądać śmiesznie, ale wyjaśnienie jest:

// Raise the index of this spliterator to be the next set bit 
// from the mid point 
index = nextSetBit(mid, wordIndex(hi - 1)); 

Tak więc dla BitSet miało to miejsce tylko raz i nie ma sensu zgłaszanie SUBSIZED, ponieważ podział nie nastąpiłby dokładnie w środku.

Na odwrót nie ma sensu: zgłaszać SUBSIZED, ale nie SIZED, więc nikt (o ile wyglądałem w kodzie) nie robi tego.