2017-01-20 39 views
13

Jestem nowy w koncepcji leniwe oceny. Kiedy wykonuję ten wiersz kodu w Scali;Scala Stream vs Java Stream Leniuchowanie Różnica

"12334".grouped(1).toStream.filter{n => println("n:" +n); n=="3";} 

To wypisuje:

n:1 
n:2 
n:3 

Ale kiedy uruchomić coś podobnego w Javie, jak:

List<String> myList = new ArrayList<>(Arrays.asList("12334".split(""))); 

Stream<String> myList2 = myList.stream().filter(a -> {System.out.println("a:" +a);return "3".equals(a);}); 

To kończy cichu bez pisania czegokolwiek pocieszyć linię. Zachowanie Javy wydaje mi się bardziej uzasadnione, ponieważ strumienie są leniwie oceniane i nie zbierałem ani nie próbowałem drukować wyniku. Ale w Scali, nawet gdybym nie zużywał strumienia, wydrukowałby pewne informacje. Więc moje pytanie jest przyczyną tej różnicy?

Odpowiedz

10

Wynika to z faktu, że filter nie jest całkowicie leniwy. Ma ten kawałek kodu:

while (!rest.isEmpty && !p(rest.head)) rest = rest.tail 

co powoduje materializację i rzeczywiste filtrowanie Stream.

Jeśli chcesz pełną lenistwo, iść z withFilter:

"12334".grouped(1).toStream.withFilter { n => println("n:" +n); n=="3"; } 

uzyskać więcej zobacz withFilter instead of filter.