1. การรวบรวมองค์ประกอบ

ในที่สุด เราก็มาถึงวิธีการที่น่าสนใจที่สุดในStreamคลาสนี้ นั่นคือcollect()วิธีการ ใช้เพื่อย้ายจากสตรีมไปยังคอลเล็กชันที่เราคุ้นเคย — List<T>, Set<T>, Map<T, R>และอื่นๆ

วิธีcollect()การใช้วัตถุพิเศษcollectorเป็นอาร์กิวเมนต์ ออบเจกต์นี้อ่านข้อมูลทั้งหมดจากสตรีม แปลงเป็นคอลเล็กชันประเภทเฉพาะ และส่งกลับ จากนั้นวิธีการรวบรวมจะส่งคืนคอลเล็กชันนี้

ทั้งหมดนี้ทำในลักษณะที่ค่อนข้างลื่นไหล: collectorประเภทของวัตถุCollector<T, A, R>คือ อย่างที่คุณเห็น มีพารามิเตอร์สามประเภท พารามิเตอร์ประเภทสุดท้าย ( R) มักจะเป็นประเภทList<T>เช่น ซึ่งหมายความว่าคอมไพลเลอร์สามารถใช้ประเภทนี้เพื่อกำหนดประเภทการส่งคืนที่ถูกต้องสำหรับเมธอดcollect()ได้

ฉันหวังว่าคุณจะไม่สับสนเกินไป ไม่ว่าในกรณีใด คุณไม่จำเป็นต้องสร้าง Collector Object ด้วยตัวเอง วัตถุสำเร็จรูปที่ส่งคืนโดยวิธีการแบบคงที่ของCollectorsคลาสจะเพียงพอ

คลาสนักสะสม

คลาสCollectorsมีเมธอดแบบสแตติกหลายวิธีที่ส่งคืนออบเจกต์ตัวสะสมสำเร็จรูป — บางอย่างสำหรับทุกโอกาส ที่นี่เราจะพิจารณาสิ่งที่สำคัญที่สุด

toList()
ออบเจกต์ที่แปลงสตรีมเป็นรายการ ( List<T>)
toSet()
ออบเจกต์ที่แปลงสตรีมเป็นชุด ( Set<T>)
toMap()
วัตถุที่แปลงสตรีมเป็นแผนที่ ( Map<K, V>)
joining()
เชื่อมองค์ประกอบของสตรีมเป็นสตริงเดียว
mapping()
แปลงองค์ประกอบของสตริงเป็นMap<K, V>
groupingBy()
จัดกลุ่มองค์ประกอบและส่งกลับMap<K, V>

2. แปลงสตรีมเป็นรายการ

ต่อไปนี้คือตัวอย่างทั่วไปของการทำงานกับสตรีมและแปลงผลลัพธ์เป็นรายการ

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

เราได้กระแสจากการรวบรวม จากนั้นเราได้สตรีมใหม่โดยคงไว้เฉพาะสตริงที่มีอักขระตัวแรกเป็นตัวพิมพ์ใหญ่ จากนั้นข้อมูลทั้งหมดจากสตรีมนั้นจะถูกรวบรวมเป็นคอลเลกชั่นซึ่งจะถูกส่งกลับ



3. แปลงสตรีมเป็นชุด

ต่อไปนี้คือตัวอย่างทั่วไปของการทำงานกับสตรีมและแปลงผลลัพธ์เป็นชุด

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

ทุกอย่างคล้ายกับรหัสสำหรับการแปลงสตรีมเป็น a Listเพียงแต่เราใช้วัตถุตัวรวบรวมที่แตกต่างกัน ซึ่งส่งคืนโดยtoSet()เมธอด



4. แปลงสตรีมเป็นแผนที่

แต่การแปลงสตรีมเป็นแผนที่นั้นยากกว่าเล็กน้อย แต่ละรายการในแผนที่ประกอบด้วยสององค์ประกอบ: คีย์และค่า เราต้องหาวิธีที่เราจะกำหนดคีย์และค่าสำหรับแต่ละองค์ประกอบในสตรีม

ตัวอย่าง:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

ลองมาดูกันว่าเกิดอะไรขึ้นที่นี่

ในบรรทัดแรก เราใช้map(...)ในการแปลงสตริงแต่ละสตริงเป็นอาร์เรย์ของสตริง ใช้วิธีแยก เราแบ่งแต่ละสตริงออกเป็นสองส่วน

ในบรรทัดที่สอง เราส่งผ่านไปยังfilter()เมธอดเฉพาะอาร์เรย์ที่มีองค์ประกอบสององค์ประกอบเท่านั้น สตริงd==3ถูกแบ่งออกเป็นอาร์เรย์ของสามองค์ประกอบ ซึ่งไม่ตรงกับตัวกรอง

และสุดท้าย ในบรรทัดสุดท้าย เราแปลงสตรีมเป็นMap<String, String>. สองฟังก์ชันถูกส่งไปยังtoMap()เมธอด สำหรับแต่ละองค์ประกอบของสตรีมฟังก์ชันแรกควรส่งคืนคีย์และฟังก์ชันที่สองส่งคืนค่า

องค์ประกอบแรกของแต่ละอาร์เรย์ ("a", "b", "c") จะเป็นคีย์ของเรา และองค์ประกอบที่สองของแต่ละอาร์เรย์ ("2", "3", "4") จะเป็นค่าของเรา



5. การแปลงสตรีมเป็นสตริง

วัตถุสะสมที่น่าสนใจอีกชิ้นถูกส่งคืนโดยCollectors.joining(). มันแปลงองค์ประกอบทั้งหมดของสตรีมStringและเชื่อมเข้าด้วยกันเป็นสตริงเดียว ตัวอย่าง

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );