ในบล็อกโพสต์นี้ เราจะพูดถึงฟีเจอร์ Java 8 Streams และให้ตัวอย่างโค้ดต่างๆ มากมาย
Java Streams นำการเขียนโปรแกรมเชิงฟังก์ชันมาสู่ java และได้รับการสนับสนุนโดยเริ่มใน java 8 ดังนั้นหากคุณมี java เวอร์ชันเก่า คุณต้องอัปเกรดเป็น java 8 เพื่อใช้ Java Streams
เหตุใดจึงควรใช้ Java Streams
ข้อดีบางประการของสตรีม:
- สตรีมจะทำให้คุณเป็นโปรแกรมเมอร์ Java ที่มีประสิทธิภาพมากขึ้น (คุณจะเห็นว่าด้วยโค้ดเพียงไม่กี่บรรทัด คุณสามารถประสบความสำเร็จได้มากโดยใช้สตรีม)
- ใช้นิพจน์แลมบ์ดาอย่างหนักซึ่งเป็นฟังก์ชันที่ใช้แล้วทิ้ง
- ParallelStreams ช่วยให้ดำเนินการแบบมัลติเธรดสำหรับชุดข้อมูลขนาดใหญ่ได้ง่ายมาก
สตรีมไปป์ไลน์
ในกรณีส่วนใหญ่ ไปป์ไลน์สตรีมประกอบด้วย
- ที่มา (ที่ที่ข้อมูลของคุณไหลออก)
- ตามด้วยศูนย์หรือมากกว่า การดำเนินการระดับกลาง
- และ การทำงานของเทอร์มินัล
แหล่งที่มากำลังจะสตรีมองค์ประกอบต่างๆ
สตรีมขององค์ประกอบนั้นสามารถกรอง จัดเรียง หรือแมปหรือชุดการดำเนินการอื่น ๆ ที่ใช้กับแต่ละองค์ประกอบได้
ในตอนท้ายสามารถรวบรวมหรือลดหรือดำเนินการอื่น ๆ ของเทอร์มินัล แต่ดำเนินการเพียงเทอร์มินัลเดียวเท่านั้น
แหล่งที่มาของสตรีม
แหล่งที่มาของสตรีม สามารถมาจากคอลเล็กชัน รายการ ชุด อาร์เรย์ของ int, longs, double, strings เป็นต้น
การทำงานของสตรีม
การสตรีม เป็นตัวกลางหรือขั้ว:
- การดำเนินการขั้นกลาง เช่น ตัวกรอง แผนที่ หรือการจัดเรียง ส่งคืนสตรีม เพื่อให้เราสามารถเชื่อมโยงการดำเนินการระหว่างกลางได้หลายรายการ
- การทำงานของเทอร์มินัล รับสตรีมและพวกเขาสามารถคืนค่าเป็นโมฆะหรือสามารถส่งคืนผลลัพธ์ที่ไม่ใช่สตรีมเช่นการลดลงเช่น ลดรายการลงในรายการ
ปฏิบัติการระดับกลาง
- อนุญาตให้ดำเนินการขั้นกลางเป็นศูนย์หรือมากกว่าได้
- เรื่องการสั่งซื้อ; สำหรับชุดข้อมูลขนาดใหญ่:กรองก่อน แล้วจัดเรียงหรือแมป
- สำหรับชุดข้อมูลขนาดใหญ่มาก เรา ParallelStream เพื่อเปิดใช้งานหลายเธรด
การดำเนินการขั้นกลางบางส่วน ได้แก่:
- anyMatch()
- distinct()
- ตัวกรอง ()
- findFirst()
- แผนผัง()
- แผนที่()
- ข้าม()
- เรียงลำดับ()
การทำงานของเทอร์มินัล
อนุญาตให้ใช้งานเทอร์มินัลได้เพียงเครื่องเดียวเท่านั้น
- forEach ใช้ฟังก์ชันเดียวกันกับแต่ละองค์ประกอบ เช่น พิมพ์แต่ละองค์ประกอบ
- collect บันทึกองค์ประกอบทั้งหมดลงในคอลเลกชันหรือรายการหรืออาร์เรย์
- ตัวเลือกอื่นๆ ทั้งหมดจะลดสตรีมเป็นองค์ประกอบสรุปเดียว
ตัวอย่างของฟังก์ชันลดได้แก่:
- นับ()
- สูงสุด()
- นาที()
- ลด()
ตัวอย่างโค้ด Java Streams
ตอนนี้เรามาดูแนวคิดข้างต้นในตัวอย่างโค้ดกัน
สตรีมจำนวนเต็ม
ตัวอย่างแรกเป็นเพียงกระแสข้อมูลจำนวนเต็ม เราจะสร้างสตรีมจำนวนเต็มโดยใช้ IntStream
class และฟังก์ชัน range ซึ่งให้ช่วงของจำนวนเต็มแก่เรา
forEach
คือการดำเนินการเทอร์มินัลของเรา สำหรับแต่ละรายการเราจะพิมพ์ออกมา
import java.io.IOException;
import java.util.stream.IntStream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream
.range(1, 10)
.forEach(System.out::print);
System.out.println();
}
}
เอาท์พุต:
123456789
สตรีมจำนวนเต็มพร้อมการข้าม
ตัวอย่างที่สองใช้สตรีมจำนวนเต็ม แต่เราเพิ่ม skip()
ในกรณีนี้ เราจะข้าม 5 องค์ประกอบแรกของสตรีม
นี่จะเป็นการพิมพ์องค์ประกอบ 6 ถึง 9 เท่านั้น เรายังใช้นิพจน์แลมบ์ดาอย่างง่ายเพื่อพิมพ์รายการด้วย
import java.io.IOException;
import java.util.stream.IntStream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream
.range(1, 10)
.skip(5)
.forEach(x -> System.out.println(x));
System.out.println();
}
}
เอาท์พุต:
6
7
8
9
สตรีมจำนวนเต็มพร้อมผลรวม
ตัวอย่างที่สาม เราใช้ IntStream
. อีกครั้ง เพื่อสร้างกระแสของวัตถุ อย่างไรก็ตาม เราใส่สิ่งนั้นไว้ใน println()
คำสั่งเป็นพารามิเตอร์สำหรับบรรทัดการพิมพ์
สิ่งที่เราจะพิมพ์ก็แค่ผลรวมจากช่วง 1 ถึง 5 หรืออีกนัยหนึ่งคือ 1 2 3 &4 จะพิมพ์เฉพาะผลรวมของตัวเลขเหล่านั้น:
import java.io.IOException;
import java.util.stream.IntStream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
System.out.println(
IntStream
.range(1, 5)
.sum());
System.out.println();
}
}
เอาท์พุต:
10
Stream.of
ตัวอย่างต่อไปใช้ Stream.of
ซึ่งสะดวกมากเพราะคุณสามารถสตรีมจำนวนเต็ม ค่าทศนิยม สตริง หรือแม้แต่อ็อบเจกต์ได้
ในตัวอย่างนี้ เราจะทำการเรียงลำดับตามตัวอักษรตรงๆ จากนั้นเราจะค้นหารายการแรกโดยใช้ findFirst()
การทำงาน. จากนั้นเราก็พิมพ์รายการแรกในรายการ
import java.io.IOException;
import java.util.stream.Stream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream.of("Ava", "Aneri", "Alberto")
.sorted()
.findFirst()
.ifPresent(System.out::println);
}
}
เอาท์พุต
Alberto
สตรีมจาก Array จัดเรียง กรอง และพิมพ์
ในตัวอย่างต่อไป เราจะสตรีมจากอาร์เรย์ จากนั้นเราจะทำการจัดเรียง กรอง และพิมพ์
ในที่นี้ เราจะกรองเฉพาะรายการที่ขึ้นต้นด้วย s
.
เราใช้นิพจน์แลมบ์ดาที่รับ X
ซึ่งเป็นชื่อแต่ละชื่อ แล้วตรวจสอบว่าชื่อใดขึ้นต้นด้วยตัวอักษร s
แล้วจะส่งต่อให้ครับ
จากนั้นเราจะจัดเรียงพวกมัน และสำหรับแต่ละรายการที่ผ่านประเภทนั้น เราจะพิมพ์ออกมา
import java.io.IOException;
import java.util.Arrays;
public class JavaStreams {
public static void main(String[] args) throws IOException {
String[] names = {"Al", "Ankit", "Kushal", "Brent", "Sarika", "amanda", "Hans", "Shivika", "Sarah"};
Arrays.stream(names)
.filter(x -> x.startsWith("S"))
.sorted()
.forEach(System.out::println);
}
}
เอาท์พุต:
Sarah
Sarika
Shivika
ค่าเฉลี่ยของอาร์เรย์จำนวนเต็ม
ตอนนี้เรามาดูกันว่าเราจะหาค่าเฉลี่ยของกำลังสองของอาร์เรย์ int ได้อย่างไร
ที่นี่เราใช้ Arrays.stream()
เพื่อสตรีมจำนวนเต็ม จากนั้นเราจะใช้ map()
เพื่อแมปแต่ละรายการจำนวนเต็มแต่ละจำนวนกับกำลังสองของแต่ละรายการ
import java.util.Arrays;
public class JavaStreams {
public static void main(String[] args) {
Arrays.stream(new int[] {2, 4, 6, 8, 10})
.map(x -> x * x)
.average()
.ifPresent(System.out::println);
}
}
เอาท์พุต:
44.0
โปรดทราบว่ามันพิมพ์ออกมาเป็นสองเท่าแทนที่จะเป็นจำนวนเต็ม
สตรีมจากรายการ กรองและพิมพ์
ในตัวอย่างนี้ เราจะสตรีมจากรายการ กรองรายการเหล่านั้นแล้วพิมพ์
โปรดทราบว่าภายใน map()
ฟังก์ชัน เราจะแปลงชื่อทั้งหมดเป็นตัวพิมพ์เล็ก
import java.util.Arrays;
import java.util.List;
public class JavaStreams {
public static void main(String[] args) {
List<String> people = Arrays.asList("Al", "Ankit", "Brent", "Sarika", "amanda", "Hans", "Shivika", "Sarah");
people
.stream()
.map(String::toLowerCase)
.filter(x -> x.startsWith("a"))
.forEach(System.out::println);
}
}
เอาท์พุต:
al
ankit
amanda
เราจะเห็นว่าเรามีชื่อสามชื่อที่ขึ้นต้นด้วย a
และทั้งหมดเป็นตัวพิมพ์เล็ก
สตรีมแถวจากไฟล์ข้อความ จัดเรียง กรอง และพิมพ์
ในตัวอย่างต่อไป เราจะสตรีมแถวจากไฟล์ข้อความ เราจะทำการจัดเรียง กรอง และพิมพ์
สมมติว่าเรามีไฟล์ชื่อ bands.txt
โดยมีเนื้อหาดังต่อไปนี้:
Rolling Stones
Lady Gaga
Jackson Browne
Maroon 5
Arijit Singh
Elton John
John Mayer
CCR
Eagles
Pink
Aerosmith
Adele
Taylor Swift
เราจะใช้ Files.lines()
เพื่อสร้างสตรีมของเราซึ่งจะทำให้เรามีสตรีมของสตริงสำหรับแต่ละบรรทัดของไฟล์
เมื่อเรามีสตรีมแล้ว เราจะจัดเรียงและกรองรายการที่มีอักขระมากกว่า 13 ตัวออก แล้วพิมพ์รายการที่เหลือ
สุดท้ายเราต้องปิดไฟล์จึงทำ bands.close
.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream<String> bands = Files.lines(Paths.get("bands.txt"));
bands
.sorted()
.filter(x -> x.length() > 13)
.forEach(System.out::println);
bands.close();
}
}
เอาท์พุต:
Jackson Browne
Rolling Stones
เราได้สองวงดนตรีที่มีอักขระมากกว่า 13 ตัว
สตรีมแถวจากไฟล์ข้อความและบันทึกลงในรายการ
สำหรับตัวอย่างนี้ เราจะใช้ไฟล์ข้อความเดียวกับด้านบน
เราต้องการกรองรายการที่มีตัวอักษร jit
โดยใช้ x.contains()
ซึ่งเป็นเพียงฟังก์ชันสตริง
การใช้ .collect()
เราเพิ่มทั้งหมดด้วยตัวอักษร jit
ในรายการ
เมื่อได้รายชื่อแล้ว เราก็สามารถใช้ forEach
ตัวดำเนินการพิมพ์รายการ
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class JavaStreams {
public static void main(String[] args) throws IOException {
List<String> bands2 = Files.lines(Paths.get("bands.txt"))
.filter(x -> x.contains("jit"))
.collect(Collectors.toList());
bands2.forEach(x -> System.out.println(x));
}
}
เอาท์พุต:
Arijit Singh
สตรีมแถวจากไฟล์ CSV และนับ
ในตัวอย่างนี้ เราสตรีมแถวจากไฟล์ CSV และเราจะนับแถวที่ดี
สมมติว่าเรามีไฟล์ชื่อ data.txt
โดยมีเนื้อหาดังต่อไปนี้:
A,12,3.7
B,17,2.8
C,14,1.9
D,23,2.7
E
F,18,3.4
ในที่นี้ แถว E ไม่มีข้อมูล เราจึงต้องการแยกข้อมูลนั้นออกจากสตรีมของเรา
ในโค้ดต่อไปนี้ เราจะอ่านในแต่ละแถว จากนั้นเราต้องแยกเครื่องหมายจุลภาคออกเป็นอาร์เรย์ เพื่อให้แต่ละแถวกลายเป็นอาร์เรย์ของรายการ
จากนั้นเราใช้ตัวกรองเพื่อกรองแถวที่ไม่มีสามรายการออก
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream<String> rows1 = Files.lines(Paths.get("data.txt"));
int rowCount = (int)rows1
.map(x -> x.split(","))
.filter(x -> x.length == 3)
.count();
System.out.println(rowCount + " rows.");
rows1.close();
}
}
เอาท์พุต:
5 rows
ลด - ผลรวม
ตัวอย่างนี้แสดงให้คุณเห็นถึงวิธีการใช้การลดลง เราจะลดให้เหลือผลรวม ที่นี่ เรามีสตรีมคู่โดยใช้ Stream.of()
การทำงาน. เราได้กำหนดสามคู่ในสามอาร์กิวเมนต์ที่แตกต่างกันและเราจะใช้ฟังก์ชันลด
import java.util.stream.Stream;
public class JavaStreams {
public static void main(String[] args) {
double total = Stream.of(7.3, 1.5, 4.8)
.reduce(0.0, (Double a, Double b) -> a + b);
System.out.println("Total = " + total);
}
}
เอาท์พุต:
13.600000000000001