Jak działa sortowanie za pomocą strumienia Java 8 pod maską?

10

Kiedy dzwonię, Stream.sort(..)czy tworzona jest nowa tablica elementów, a strumień iteruje po nowo utworzonej posortowanej tablicy?

Innymi słowy, jak Java 8 Stream działa sortpod maską?

Poinformowano
źródło
Dlaczego dostaję głos negatywny z tym pytaniem?
InformedA
2
Twoje pytanie jest uzasadnione i nie zasługuje na opinie. Wasze komentarze do odpowiedzi Amona jednak ... ugh: |
Andres F.
@AndresF. Głosowanie w dół nastąpiło jeszcze zanim wypowiedziałem się. To jeden z powodów, dla których byłem bardzo zdenerwowany.
InformedA
W każdym razie komentarze nie stanowią powodu do głosowania. Pytanie ma swoją wartość i moim zdaniem jest ważne. Głosowałem za tym.
Andres F.

Odpowiedzi:

10

Możesz użyć grepcode.com, aby przeszukać standardowy kod biblioteki Java (i niektóre inne biblioteki). Niestety kod implementacji strumienia jest raczej abstrakcyjny. Dobrym punktem wyjścia jest java.util.stream.SortedOpsklasa wewnętrzna, która przekształca strumień w posortowany strumień.

Prąd realizacja (stosowany dla strumieni standardowych kontenerów biblioteki) sprawia, że rozkaz pusty, jeżeli strumień jest już posortowana wykorzystuje tablicę jeżeli wielkość strumienia jest znany ( SizedRefSortingSink) lub gromadzi wszystkie elementy ArrayList Jeżeli rozmiar nieznany ( RefSortingSink).

Oczywiście takie szczegóły implementacji mogą ulec zmianie w każdej wersji, ale podstawowe uwagi są uniwersalne: Sortowanie strumienia jest koniecznie operacją chętną / blokującą, a sortowanie strumienia nieskończonego nie ma znaczenia. Oznacza to, że sortowanie strumienia nie jest przydatne, jeśli używasz strumieni, ponieważ mogą być leniwe, ale nadal masz wygodną składnię strumienia.

Inne strumienie będą musiały zapewnić własną implementację Stream.sorted(), która prawdopodobnie będzie podobna.

amon
źródło
1
@InformedA Nie chcę sugerować, że lambdas lub strumienie byłyby „bzdurami pod maską”. Oba są niezwykle wygodne, mimo że szczegóły dotyczące strumieni są niezwykle złożone w porównaniu do innych koncepcji Java. Jeśli chcesz trzymać się z góry założonego poglądu, że narzędzia te są bezużyteczne lub szkodliwe, niepotrzebnie się ograniczasz.
amon
1
@amon - uzgodniono, a strumienie zapewniają możliwość zwijania równoległych wielordzeniowych implementacji pod maską, bez wirtualnej zmiany aplikacji. I właśnie z tego wynika złożoność implementacji strumienia. To coś więcej niż wygoda, odpowiednia abstrakcja. Do OP - proponuję przeczytać Mastering Lambdas ... jeśli chcesz zrozumieć, dlaczego lambdas i strumienie są czymś więcej niż tylko wygodnymi funkcjami.
Yuri Steinschreiber
3
@InformedA: lambdas istnieje od 80 lat i istnieje w prawie każdym obecnym języku programowania głównego nurtu. Strumienie istnieją już od 40 lat i podobnie istnieją w prawie wszystkich ramach głównego nurtu kolekcji. Można je nazwać różnymi rzeczami (iteratory, leniwe listy, wyliczacze, wyliczenia), ale one tam są. Lambda i leniwe listy to jedne z najstarszych i najbardziej stabilnych abstrakcji, które przetrwały każdą nową modę, szum, paradygmat, ruch, metodologię, technologię, język, system operacyjny, framework, bibliotekę. To sprawia, że ​​warto na nie spojrzeć.
Jörg W Mittag
2
@Informed Java, język programowania, to po prostu bzdura abstrakcja kodu bajtowego uruchomionego na JVM. Sama JVM jest po prostu bzdurną abstrakcją napisaną w C (lub C ++, zapominam). C i C ++ są po prostu bzdurnymi abstrakcjami nad językiem asemblera. Nawet sam asembler to abstrakcja bzdur nad mikrokodem, która jest także abstrakcją bzdur nad obwodami (ok, może brakuje mi kilku kroków pomiędzy nimi). Można powiedzieć, że wszystko przydatne w oprogramowaniu to „bzdura abstrakcja” w stosunku do czegoś innego.
Andres F.
3
@InformedA Moja szczera rada jest taka, że ​​próbujesz nauczyć się języka, który jest bardziej zorientowany na programowanie funkcjonalne niż Java. Nawet jeśli nigdy nie użyjesz go do codziennej pracy, zrozumiesz języki programowania i ich opcje projektowania, które pomogą ci w Javie :)
Andres F.