2015-04-14 20 views
11

Czy strumienie Java 8 są bezpiecznymi typami powrotu dla metod publicznych, ponieważ nie można zmutować obiektu bazowego, z którego pochodzi strumień?Czy Java 8 jest bezpiecznym typem zwrotnym?

Na przykład, jeśli mam List i return list.stream();, czy wartość zwracaną w jakikolwiek sposób można wykorzystać do mutowania oryginalnej listy?

Sądząc z API, nie sądzę, że jest to możliwe, ale chciałbym potwierdzić.

+2

zapoznanie się i dostaniesz dobrą pojęcia dlaczego strumienie nie będą modyfikować źródło (zbiór w przykładzie): http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html – alfasin

+4

Uzyskiwanie strumienia z listy nie powinno modyfikować samej struktury danych, ale może modyfikować jej treść, jeśli zawiera zmienne obiekty. Ale ta zasada dotyczy ogólnie struktur danych. –

Odpowiedz

13

Tak, można to bezpiecznie zrobić. Strumienie nie/nie powinny modyfikować podstawowej struktury danych.

Kilka fragmenty java.util.stream.Stream:

sekwencji elementów hellip [b].

Kolekcje i strumienie, choć mają pewne powierzchowne podobieństwa, mają różne cele. Kolekcje dotyczą przede wszystkim sprawnego zarządzania i dostępu do ich elementów. Dla kontrastu, strumienie nie zapewniają środków do bezpośredniego dostępu lub manipulowania ich elementami [& hellip;].

Aby zachować prawidłowe zachowanie, [parametry behawioralne do operacji strumieniowych i hellip;] muszą być niezakłócone (nie modyfikują źródła strumienia).

I od Package java.util.stream Description:

Strumienie różnią się od zbiorów na kilka sposobów:

  • Brak pamięci. Strumień nie jest strukturą danych, która przechowuje elementy; zamiast tego przenosi elementy ze źródła [& hellip;], poprzez potok operacji obliczeniowych.
  • Funkcjonalny charakter. Operacja na strumieniu daje wynik, ale nie modyfikuje jego źródła.

Można również zobaczyć Non-interference.


[b hellip;] Byłoby niemożliwe mutować podstawowy obiekt danych w strumieniu od niej.

Chociaż byłoby możliwe napisać naszą własne realizację java.util.Stream że zmodyfikował podstawowej struktury danych, byłoby błędem, aby to zrobić. ;)


W odpowiedzi na komentarz przez @AlexisC.:

Pierwsze strumienia z listy [& hellip;] można zmodyfikować jego zawartości jeśli zawiera zmienny obiektów.

To jest punkt sprawiedliwy. Jeśli mamy strumień elementów, które są zmienne możemy zrobić:

myObj.stream().forEach((Foo foo) -> (foo.bar = baz)); 
+0

Oczywiście z wyjątkiem refleksji. Nie próbowałem tego, ale byłbym bardzo zaskoczony, gdyby nie można było użyć refleksji, aby uzyskać dostęp i zmodyfikować podstawową strukturę strumienia. – kajacx

+0

Aby wyjaśnić, sama kolekcja nie może być modyfikowana przez strumień, ale elementy mogą być modyfikowane. Jeśli nie chcesz, aby same elementy zostały zmodyfikowane, uczyń je niezmiennymi przez końcowe i hermetyzację. – tmn

+4

@kajacx Byłoby możliwe uzyskanie odniesienia do podstawowej struktury danych za pomocą refleksji, ale to samo można powiedzieć o niezmienności w Javie. Nic nie jest niezmienne, jeśli chcesz napisać jakiś hacky kod. To samo dotyczy np. 'Collections.unmodifiableList'. – Radiodef

Powiązane problemy