พิจารณาสิ่งList<String> stringList
ที่สามารถพิมพ์ได้หลายวิธีโดยใช้การสร้างJava 8 :
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)
วิธีการเหล่านี้แตกต่างจากกันอย่างไร
First Approach ( Iterable.forEach
) -
ตัววนซ้ำของคอลเลกชันถูกใช้โดยทั่วไปและถูกออกแบบมาให้ล้มเหลวอย่างรวดเร็วซึ่งหมายความว่ามันจะโยนConcurrentModificationException
หากคอลเลกชันพื้นฐานถูกปรับเปลี่ยนโครงสร้างในระหว่างการทำซ้ำ ตามที่กล่าวไว้ในเอกสารสำหรับArrayList
:
การดัดแปลงโครงสร้างเป็นการดำเนินการใด ๆ ที่เพิ่มหรือลบองค์ประกอบหนึ่งรายการขึ้นไปหรือปรับขนาดอาร์เรย์สำรองอย่างชัดเจน เพียงการกำหนดค่าขององค์ประกอบไม่ใช่การปรับเปลี่ยนโครงสร้าง
ดังนั้นมันหมายถึงการArrayList.forEach
ตั้งค่าที่อนุญาตโดยไม่มีปัญหาใด ๆ และในกรณีที่มีการรวบรวมพร้อมกันเช่นConcurrentLinkedQueue
ตัววนซ้ำนั้นจะมีความสอดคล้องกันอย่างอ่อนซึ่งหมายความว่าการกระทำที่ผ่านforEach
นั้นได้รับอนุญาตให้ทำการเปลี่ยนแปลงโครงสร้างได้โดยไม่ต้องConcurrentModificationException
ถูกยกเว้น แต่ที่นี่การแก้ไขอาจหรือไม่อาจมองเห็นได้ในการทำซ้ำนั้น
Second Approach ( Stream.forEach
) -
คำสั่งไม่ได้ถูกกำหนด แม้ว่ามันอาจจะไม่เกิดขึ้นสำหรับลำธารเรียงตามลำดับ แต่สเปคไม่ได้รับประกัน นอกจากนี้การกระทำจะต้องไม่รบกวนธรรมชาติ ตามที่ระบุไว้ในdoc :
พฤติกรรมของการดำเนินการนี้เป็นแบบไม่ระบุชื่ออย่างชัดเจน สำหรับท่อส่งกระแสคู่ขนานการดำเนินการนี้ไม่รับประกันว่าจะเคารพต่อคำสั่งซื้อของลำธารเนื่องจากการทำเช่นนั้นจะเสียสละประโยชน์ของการขนาน
Third Approach ( Stream.forEachOrdered
) -
การดำเนินการจะดำเนินการตามลำดับการเผชิญหน้าของสตรีม ดังนั้นเมื่อใดก็ตามที่ลำดับการใช้forEachOrdered
มีความสำคัญ ตามที่ระบุไว้ในเอกสาร :
ดำเนินการกับแต่ละองค์ประกอบของสตรีมนี้ตามลำดับพบของสตรีมหากสตรีมมีลำดับการเผชิญหน้าที่กำหนดไว้
ในขณะที่การทำซ้ำมากกว่าการเก็บรวบรวมข้อมูลให้ตรงกันวิธีแรกจะใช้เวลาล็อคคอลเลกชันครั้งและจะถือมันในทุกสายไปยังวิธีการดำเนินการ แต่ในกรณีของลำธารที่พวกเขาใช้ spliterator คอลเลกชันที่ไม่ได้ล็อคและอาศัยอยู่กับกฎระเบียบที่จัดตั้งขึ้นแล้วไม่ใช่ -การรบกวน. ในกรณีที่คอลเลกชันสำรองกระแสถูกแก้ไขในระหว่างการทำซ้ำConcurrentModificationException
อาจจะโยนหรือผลลัพธ์ที่ไม่สอดคล้องกันอาจเกิดขึ้น
Fourth Approach (Parallel Stream.forEach
) -
ตามที่ได้กล่าวมาแล้วไม่มีการรับประกันว่าจะเคารพคำสั่งเผชิญหน้าตามที่คาดไว้ในกรณีของการสตรีมแบบขนาน เป็นไปได้ว่าการกระทำนั้นกระทำในเธรดที่แตกต่างกันสำหรับองค์ประกอบต่าง ๆ ซึ่งไม่สามารถเกิดforEachOrdered
ขึ้นได้
Fifth Approach (Parallel Stream.forEachOrdered
) -
The forEachOrdered
จะประมวลผลองค์ประกอบตามลำดับที่ระบุโดยแหล่งที่มาโดยไม่คำนึงถึงความจริงที่ว่ากระแสเป็นลำดับหรือขนาน ดังนั้นจึงไม่มีเหตุผลที่จะใช้สิ่งนี้กับสตรีมแบบขนาน
List
เป็นคนแบบไหน? แสดงวิธีที่คุณประกาศและสร้างอินสแตนซ์