2015-05-12 13 views
5

Natknąłem się na interesujący szczegół w java.util.Spliterator (Java 8).Spliterator typ zwrotu trySplit

Metoda trySplit() ma zwrócić instancję Spliteratora lub null, jeśli nie można jej podzielić. Java doc mówi co następuje:

* @return a {@code Spliterator} covering some portion of the 
* elements, or {@code null} if this spliterator cannot be split. 

Wydaje mi się jako idealne miejsce do wykorzystania java.util.Optional. Jak na javadoc:

* A container object which may or may not contain a non-null value. 

Czy istnieją powody, dla których nie użyto opcji Opcjonalne?

Googling nie pomógł dużo, z wyjątkiem tego question na liście mailingowej lambda-dev, na którą nie udzielono odpowiedzi.

Odpowiedz

10

Istnieje kilka powodów, dla których tak właśnie jest. Oczywiście, koncepcyjnie, trySplit może zwrócić , ale są pewne siły konstrukcyjne, które odepchnęły od tego.

Jednym z powodów jest to, że nie ma różnicy między metodami, takimi jak findFirst zwracające Optional porównaniu z metodami takimi jak trySplit zwracające od wartości lub null.

  • Metody takie jak findFirst nazywane są i powrót wartości kodu aplikacji.
  • Metody takie jak trySplit zwołuje i powrócić do wartości biblioteki kodu.

Aspektem projektowania bibliotek klas JDK jest to, że interfejsy API bibliotek są (lub powinny być) zaprojektowane tak, aby uprościć kod aplikacji, a kod biblioteki często nabiera większej złożoności, aby uprościć Aplikacje.

Jednym z głównych powodów dla Optional jest unikanie przekazywania wartości null z biblioteki do kodu aplikacji, ponieważ niewłaściwa obsługa zerowa jest wspólnym źródłem NullPointerException s. Zamiast null, API jak findFirst zwróci pusty Optional, który jest obsługiwany przez bogaty zestaw metod, takich jak orElse, map, filter, flatMap itp, które zapewniają dużą elastyczność do wniosków do czynienia z nie-found walizka.

Należy zauważyć, że wartość zwracana z pustych trySplit jedzie w przeciwnym kierunku: z aplikacji do biblioteki.

uwzględniając wniosek podanie kodu lub zwrócić wartość zerowalne do biblioteki jest znacznie mniej podatne na błędy w stosowaniu niż mieć go otrzymać wartość zerowalne z biblioteki. Jeśli piszesz aplikację, a interfejs API mówi, że powinieneś przekazać lub zwrócić wartość zerową do biblioteki, nie ma możliwości, że spowoduje to wygenerowanie NPE w kodzie twojego. Rzeczywiście, w API istnieje wiele miejsc (List.sort(null)), gdzie null ma określoną semantykę w API.

jest wywoływany ze stosunkowo niewielu miejsc w bibliotece, a opiekunowie bibliotek przejmują w każdym z tych przypadków ciężar właściwego postępowania z null.

Inną podstawową sprawą jest wydajność. Dzielenie jest na krytycznej ścieżce tworzenia równoległego potoku. Jest wykonywany sekwencyjnie, zanim praca zostanie przekazana do różnych wątków do wykonania równolegle. Per Amdahl's Law, aby maksymalnie zwiększyć paralelizm, należy zminimalizować narzut na instalację sekwencyjną.

Faktem jest, że Optional jest pudełkiem, a jego koszt wiąże się z koniecznością boksowania i rozpakowywania wartości od Optional. Kompilator JIT może w niektórych przypadkach być w stanie to zoptymalizować, ale może nie. Nawet jeśli tak jest, jest okres czasu, w którym kod jest uruchomiony, ale Optional nie został jeszcze zoptymalizowany. To dodatkowy koszt. Ponieważ kod biblioteki jest w stanie udźwignąć ciężar właściwego obchodzenia się z null, możemy zagwarantować, że nie będzie żadnych obciążeń związanych z boksem, po prostu przez to, że w tym przypadku nie użyjemy Optional.

7

Spliterator jest częścią wewnętrznej realizacji strumień. Nie powinno się go używać w logice biznesowej, gdzie byłoby wygodnie. Jego dość niski poziom interfejsu, którego głównym celem jest być szybki. Więc nie ma powodu dla Optional tam.

Można argumentować, że Optional zwykle mogą być wyeliminowane przez kompilator JIT. Jednak nie zawsze tak jest. Na przykład, maksymalna maksymalna liczba wywołań do wstawiania w kompilatorze JIT Hotspot to 10, a zwykłe przetwarzanie strumienia ma więcej ramek stosu, więc nawet jedna dodatkowa ramka stosu może uniemożliwić optymalizację.

+2

Zazwyczaj 'Opcjonalny' jest rozpakowywany przez osobę dzwoniącą i nie będzie różnił się od implementacji' Stream', więc inne ramki stosów nie są ważne. – Holger

Powiązane problemy