Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ความแตกต่างระหว่าง Collection.stream().forEach() และ Collection.forEach() ใน Java

ทั้ง Collection.stream().forEach() และ Collection.forEach() ใช้สำหรับวนซ้ำ (iterate) ผ่านคอลเลกชัน แต่มีความแตกต่างสำคัญในแง่ของพฤติกรรม การจัดลำดับ และการจัดการข้อยกเว้น

ความแตกต่างหลัก

# หัวข้อ Collection.forEach() Collection.stream().forEach()
1 พื้นฐาน ใช้ Iterator ของคอลเลกชันโดยตรง แปลงคอลเลกชันเป็น Stream ก่อน แล้วจึงวนซ้ำผ่าน Stream
2 ลำดับการประมวลผล ทำงานตามลำดับการวนซ้ำของ Iterable (ถ้ามีระบุ) ลำดับไม่ได้รับการกำหนด (undefined) โดยเฉพาะกับ parallel stream
3 การล็อก (Locking) ถ้าวนซ้ำบนคอลเลกชันที่ซิงโครไนซ์ จะล็อกส่วนของคอลเลกชันและคงไว้ตลอดการเรียกใช้ ไม่ล็อกคอลเลกชัน
4 ข้อยกเว้น ConcurrentModificationException โยนข้อยกเว้นทันทีหากมีการแก้ไขโครงสร้างขณะวนซ้ำ โยนข้อยกเว้นในภายหลัง (อาจไม่ใช่ทันที)

รายละเอียดเพิ่มเติม

Collection.forEach()

เมธอดนี้ใช้ Iterator ภายในของคอลเลกชัน คอลเลกชันส่วนใหญ่ไม่อนุญาตให้แก้ไขโครงสร้าง (เพิ่ม/ลบสมาชิก) ขณะกำลังวนซ้ำ หากทำเช่นนั้นจะโยน ConcurrentModificationException ทันที นอกจากนี้ หากใช้กับคอลเลกชันที่ซิงโครไนซ์ (เช่น Collections.synchronizedList()) จะล็อกคอลเลกชันตลอดระยะเวลาการวนซ้ำ ซึ่งอาจส่งผลต่อประสิทธิภาพในสภาพแวดล้อมมัลติเธรด

Collection.stream().forEach()

เมธอดนี้แปลงคอลเลกชันเป็น Stream ก่อน แล้วจึงดำเนินการ forEach บน Stream ลำดับการประมวลผลไม่ได้รับการรับประกัน (โดยเฉพาะเมื่อใช้ parallel stream) การจัดการข้อยกเว้น concurrent modification อาจแตกต่างจาก forEach โดยตรง เนื่องจาก Stream มีกลไกภายในที่แตกต่าง

ตัวอย่างโค้ด

ตัวอย่าง Collection.stream().forEach()

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Ram");
        list.add("TutorialPoints");
        list.stream().forEach(System.out::print);
    }
}

ตัวอย่าง Collection.forEach()

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Ram");
        list.add("TutorialPoints");
        list.forEach(System.out::print);
    }
}

สรุป: ควรใช้ตัวไหน?

  • ใช้ Collection.forEach() เมื่อต้องการลำดับที่แน่นอน และทำงานกับคอลเลกชันโดยตรง
  • ใช้ Collection.stream().forEach() เมื่อต้องการใช้ประโยชน์จาก Stream API เช่น filter, map, parallel processing หรือ chaining operations
  • หลีกเลี่ยงการแก้ไขคอลเลกชันขณะวนซ้ำในทั้งสองกรณี