Java 8 yapıları List<String> stringListkullanılarak pek çok şekilde yazdırılabilecekleri düşünün :
stringList.forEach(System.out::println); // 1) Iterable.forEach
stringList.stream().forEach(System.out::println); // 2) Stream.forEach (order maintained generally but doc does not guarantee)
stringList.stream().forEachOrdered(System.out::println); // 3) Stream.forEachOrdered (order maintained always)
stringList.parallelStream().forEach(System.out::println); // 4) Parallel version of Stream.forEach (order not maintained)
stringList.parallelStream().forEachOrdered(System.out::println); // 5) Parallel version ofStream.forEachOrdered (order maintained always)
Bu yaklaşımlar birbirinden nasıl farklı?
İlk Yaklaşım ( Iterable.forEach) -
Koleksiyonun yineleyicisi genellikle kullanılır ve bu, hızlı bir şekilde tasarlanmıştır; bu da ConcurrentModificationException, alttaki koleksiyon yineleme sırasında yapısal olarak değiştirilirse atılacağı anlamına gelir . Belirtildiği gibi doc için ArrayList:
Yapısal bir değişiklik, bir veya daha fazla eleman ekleyen veya silen veya destek dizisini açıkça yeniden boyutlandıran herhangi bir işlemdir; sadece bir elemanın değerinin ayarlanması yapısal bir değişiklik değildir.
Bu nedenle ArrayList.forEach, değerin ayarlanmasına herhangi bir sorun olmadan izin verilir. Ve eşzamanlı toplama durumunda, örneğin ConcurrentLinkedQueueyineleyici, zayıf bir şekilde tutarlı olacaktır, bu da, geçirilen eylemlerin forEach, ConcurrentModificationExceptionistisnasız olarak bile yapısal değişiklikler yapmasına izin verildiği anlamına gelir . Ancak burada değişiklikler bu yinelemede görülebilir veya görünmeyebilir.
İkinci Yaklaşım ( Stream.forEach) -
Sipariş tanımsız. Sıralı akışlar için olmasa da, şartname bunu garanti etmez. Ayrıca, eylemin doğaya müdahale etmemesi gerekmektedir. Belirtildiği gibi doc :
Bu operasyonun davranışı açıkça belirsizdir. Paralel akışlı boru hatları için, bu işlem akımın karşılaşma sırasına saygı gösterilmesini garanti etmez, çünkü bunu yapmak paralelliğin faydasını feda edecektir.
Üçüncü Yaklaşım ( Stream.forEachOrdered) -
Eylem, akışın karşılaşma sırasında gerçekleştirilir. Dolayısıyla, sipariş ne zaman önemli forEachOrderedolursa, ikinci bir düşünce olmadan kullanın . Belirtildiği gibi doc :
Akış tanımlanmış bir karşılaşma sırasına sahipse, akışın karşılaşma sırasında bu akışın her öğesi için bir eylem gerçekleştirir .
Eşzamanlı bir koleksiyon üzerinde yineleme yaparken , ilk yaklaşım koleksiyonun kilidini bir kez alır ve tüm harekete geçirici mesaj yönteminde tutar, ancak akışlarda, önceden oluşturulmuş olmayan kurallara kilitlenmeyen ve güvenmeyen koleksiyonun ayırıcısını kullanırlar -girişim. Akışın iterasyon sırasında modifiye ConcurrentModificationExceptionedilmesi durumunda a atılır veya tutarsız bir sonuç ortaya çıkabilir.
Dördüncü Yaklaşım (Paralel Stream.forEach) -
Daha önce de belirtildiği gibi, paralel akışlarda karşılaşılan sıraya uyulması konusunda herhangi bir garanti verilmemektedir. Eylemin, asla böyle olmayacak farklı elemanlar için farklı bir iş parçacığında gerçekleştirilmesi mümkündür forEachOrdered.
Beşinci yaklaşım (paralel Stream.forEachOrdered) -forEachOrdered akışı, ardışık veya paralel olup bağımsız olarak aslında kaynağı tarafından belirtilen sırada elemanlarını işleyecektir. Bu yüzden bunu paralel akışlarla kullanmak mantıklı değil.
List? Bize nasıl beyan ettiğinizi ve somutlaştırdığınızı gösterin.