สตรีม API คืออะไร
Stream API เป็นวิธีใหม่ในการทำงานกับโครงสร้างข้อมูลในรูปแบบการทำงาน Stream API (คำอธิบายวิธีที่โปรแกรมคอมพิวเตอร์ตัวหนึ่งสามารถสื่อสารกับโปรแกรมอื่น) ถือเป็นกระแสข้อมูลหลัก คำว่า "thread" นั้นค่อนข้างคลุมเครือในการเขียนโปรแกรมโดยทั่วไปและโดยเฉพาะใน Java
List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
list.add("Five");
list.add("Six");
list.add("Seven");
list.add("Eight");
list.add("Nine");
list.add("Ten");
Stream stream = list.stream();
ตามที่กล่าวไว้ข้างต้น Stream API ช่วยให้คุณสามารถลดจำนวนบรรทัดของโค้ดได้ ตัวอย่างที่มีกระแส:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
ตัวอย่างที่ไม่มีเธรด:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
int count = 0;
for (int x : arr) {
if (x >= 90) continue;
x += 10;
count++;
if (count > 3) break;
System.out.print(x);
}
วิธีที่เป็นไปได้ในการสร้างสตรีม:

- สตรีมว่างเปล่า:
Stream.empty()
- สตรีมจากรายการ:
list.stream()
- สตรีมจากแผนที่:
map.entrySet().stream()
- สตรีมจากอาเรย์:
Arrays.stream(array)
- สตรีมจากองค์ประกอบที่ระบุ:
Stream.of("1", "2", "3")
- ระดับกลาง (เรียกอีกอย่างว่า "ขี้เกียจ") - ประมวลผลองค์ประกอบที่เข้ามาและส่งคืนสตรีม อาจมีตัวดำเนินการระดับกลางจำนวนมากในห่วงโซ่การประมวลผลองค์ประกอบ
- เทอร์มินัล (“เทอร์มินัล” หรือที่เรียกว่า “กระตือรือร้น”) - ประมวลผลองค์ประกอบและยุติสตรีม ดังนั้นจึงมีผู้ดำเนินการเทอร์มินัลได้เพียงคนเดียวในห่วงโซ่
1.List<String> list = new ArrayList<String>();
2.list.add("One");
…
11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
เกิดอะไรขึ้นที่นี่:
- 1 - สร้างรายการ
list
; - 2-11 - กรอกข้อมูลการทดสอบ
- 12 - สร้างวัตถุ
Stream
; - 13 - วิธีการ
filter
(ตัวกรอง) - ตัวดำเนินการระดับกลางx
เท่ากับองค์ประกอบหนึ่งของคอลเลกชันสำหรับการแจงนับ (เช่นเดียวกับfor each
) และหลังจาก -> เราระบุว่าคอลเลกชันของเราถูกกรองอย่างไร และเนื่องจากนี่คือตัวดำเนินการระดับกลาง คอลเลกชันที่กรองจึงไปเพิ่มเติมที่วิธีการ ซึ่งforEach
ในทางกลับกันคือเทอร์มินัล (สุดท้าย) อะนาล็อกของการแจงนับfor each
(นิพจน์System.out::println
ย่อมาจาก:x-> System.out.println(x))
ซึ่งจะผ่านองค์ประกอบทั้งหมดของคอลเลกชันที่ส่งผ่านไปและแสดง)

- การประมวลผลจะไม่เริ่มจนกว่าจะมีการเรียกตัวดำเนินการเทอร์มินัล
list.stream().filter(s -> s > 5)
(จะไม่รับองค์ประกอบเดียวจากรายการ) - อินสแตนซ์ของสตรีมไม่สามารถใช้งานได้มากกว่าหนึ่งครั้ง =( ;

ดังนั้นทุกครั้งที่มีรายการใหม่:
list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
list.stream().forEach(x -> System.out.println(x));
สามารถมีตัวดำเนินการระดับกลางได้หลายตัวที่ถูกเรียกในสตรีมเดียว ในขณะที่มีตัวดำเนินการเทอร์มินัลเพียงตัวเดียว:
stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));

filter(Predicate predicate)
กรองสตรีมโดยส่งเฉพาะองค์ประกอบที่ผ่านเงื่อนไข (เพรดิเคตเป็นอินเทอร์เฟซการทำงานในตัวที่เพิ่มให้กับแพ็คเกจใน Java SE 8java.util.function
ตรวจสอบค่าสำหรับ " true " และ " false ");map(Function mapper)
ทำให้สามารถสร้างฟังก์ชันที่เราจะเปลี่ยนแต่ละองค์ประกอบและข้ามไปเพิ่มเติมได้ (อินเทอร์เฟซการทำงานFunction<T,R>
แสดงถึงฟังก์ชันการเปลี่ยนจากวัตถุประเภท T ไปเป็นวัตถุประเภท R)flatMap(Function<T, Stream<R>> mapper)
- เช่นเดียวกับในกรณีของmap
พวกมันจะถูกใช้เพื่อแปลงเป็นสตรีมดั้งเดิม
[stream1,stream2,stream3,stream4] => stream
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
.collect(Collectors.toList()).forEach(System.out::println);
ในขณะที่map
แปลงเป็นรายการเธรด ( <Stream>
เธรดที่แม่นยำยิ่งขึ้น) [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.map(Arrays::stream).distinct() //Make the array into a separate thread
.collect(Collectors.toList()).forEach(System.out::println);
ข้อแตกต่างอีกประการหนึ่งเมื่อเปรียบเทียบกับmap
คุณสามารถแปลงองค์ประกอบหนึ่งให้เป็นศูนย์ หรือหนึ่งรายการหรือหลายรายการก็ได้ ในการแปลงองค์ประกอบหนึ่งให้เป็นองค์ประกอบศูนย์ คุณต้องส่งกลับnull
หรือสตรีมว่างเปล่า หากต้องการแปลงเป็นองค์ประกอบเดียว คุณจะต้องส่งคืนสตรีมจากองค์ประกอบหนึ่ง เช่นStream.of(x)
ผ่าน หากต้องการส่งคืนองค์ประกอบหลายรายการ คุณสามารถสร้างสตรีมด้วยองค์ประกอบเหล่านี้ด้วยวิธีใดก็ได้ วิธี flatMap เดียวกัน แต่สำหรับ Double, Integer และ Long:
- flatMapToDouble (ตัวทำแผนที่ฟังก์ชัน)
- flatMapToInt (ตัวทำแผนที่ฟังก์ชัน)
- flatMapToLong (ตัวทำแผนที่ฟังก์ชัน)
Stream.of(2, 3, 0, 1, 3)
.flatMapToInt(x -> IntStream.range(0, x))
.forEach(System.out::print);// 010120012
-
IntStream.range(0,x) – ส่งออกองค์ประกอบตั้งแต่ 0 (รวม) ถึง x (ไม่รวม) ไปยังสตรีม
แผนที่:
Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//list of streams (streams);
-
ขีดจำกัด(long maxSize) – จำกัดสตรีมด้วยจำนวนองค์ประกอบ:
stream.limit(5).forEach(x -> System.out.println(x));
-
ข้าม(ยาว n) – ข้ามองค์ประกอบ n:
stream.skip(3).forEach(x -> System.out.println(x));
-
เรียงลำดับ()
- sorted(ตัวเปรียบเทียบ) – เรียงลำดับสตรีม (เรียงลำดับเหมือน TreeMap):
stream.sorted().forEach(x -> System.out.println(x));
-
แตกต่าง() - ตรวจสอบสตรีมเพื่อดูเอกลักษณ์ขององค์ประกอบ (ลบการซ้ำซ้อนขององค์ประกอบ)
-
dropWhile(เพรดิเคตเพรดิเคต) - ข้ามองค์ประกอบที่ตรงตามเงื่อนไข (ปรากฏใน java 9, อินเทอร์เฟซการทำงานของเพรดิเคต<T> จะตรวจสอบว่าตรงตามเงื่อนไขที่กำหนดหรือไม่ หากเป็นไปตามนั้น จริง จะถูกส่งกลับ นิพจน์แลมบ์ดารับอ็อบเจ็กต์ของ พิมพ์ T เป็นพารามิเตอร์:
Predicate<Integer> isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false

-
forEach(Consumer action) – คล้ายคลึงกับ for Each (Consumer<T> ดำเนินการบางอย่างกับอ็อบเจ็กต์ประเภท T โดยไม่ส่งคืนสิ่งใด)
-
count() – ส่งกลับจำนวนองค์ประกอบสตรีม:
System.out.println(stream.count());
-
collect(Collector collector) – วิธีการรวบรวมองค์ประกอบทั้งหมดลงในรายการ ชุดหรือคอลเลกชันอื่น ๆ จัดกลุ่มองค์ประกอบตามเกณฑ์บางอย่าง รวมทุกอย่างไว้ในสตริง ฯลฯ:
List<String> list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList());
-
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
— เช่นเดียวกับ มีcollect(collector)
เพียงพารามิเตอร์เท่านั้นที่ถูกแจกแจงเพื่อความสะดวก (supplier
จัดหาวัตถุใหม่ (คอนเทนเนอร์) เช่นnew ArrayList()
เพิ่มaccumulator
องค์ประกอบลงในคอนเทนเนอร์combiner
รวมส่วนของสตรีมเข้าด้วยกัน) -
ลด(Tเอกลักษณ์, ตัวสะสม BinaryOperator) - แปลงองค์ประกอบทั้งหมดของสตรีมให้เป็นวัตถุเดียว (คำนวณผลรวมขององค์ประกอบทั้งหมดหรือค้นหาองค์ประกอบขั้นต่ำ) ก่อนอื่นให้นำวัตถุ
identity
และองค์ประกอบแรกของสตรีมไปใช้ฟังก์ชันaccumulator
และidentity
กลายเป็น ผลลัพธ์ของมัน จากนั้นทุกอย่างจะดำเนินต่อไปสำหรับองค์ประกอบที่เหลือint sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
-
reduce(BinaryOperator accumulator)
— วิธีการเดียวกับข้างต้น แต่ไม่มีวิธีเริ่มต้นidentity
มันเป็นองค์ประกอบแรกของสตรีมOptional min(Comparator comparator)
ตัวเลือกสูงสุด (ตัวเปรียบเทียบ) จะค้นหาองค์ประกอบขั้นต่ำ/สูงสุดตามตัวเปรียบเทียบที่ส่งผ่าน -
findFirst()
– ดึงองค์ประกอบแรกของสตรีมออกมา:Stream.of(1, 2, 3, 4, 9).findFirst();
-
allMatch(Predicate predicate)
— คืนค่าเป็นจริงหากองค์ประกอบทั้งหมดของสตรีมตรงตามเงื่อนไข หากพบองค์ประกอบใดๆ ซึ่งผลลัพธ์ของการเรียกใช้ฟังก์ชันเพรดิเคตเป็นfalseตัวดำเนินการจะหยุดการสแกนองค์ประกอบและส่งคืนค่าfalse :Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
-
anyMatch(Predicate predicate)
— จะคืนค่าเป็นจริงหากองค์ประกอบสตรีมอย่างน้อยหนึ่งองค์ประกอบตรงตามเงื่อนไขpredicate
:Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
-
noneMatch(Predicate predicate)
— จะคืนค่าเป็นจริงถ้าผ่านองค์ประกอบทั้งหมดของสตรีมแล้ว ไม่มีองค์ประกอบใดที่ตรงตามเงื่อนไขpredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
— รวบรวมองค์ประกอบเป็นList
:List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
-
toSet()
— รวบรวมองค์ประกอบเป็นชุด:Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
-
counting()
— นับจำนวนองค์ประกอบ:Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
-
joining()
-
joining(CharSequence delimiter)
-
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
— รวบรวมองค์ประกอบเป็นบรรทัดเดียว นอกจากนี้ คุณยังสามารถระบุตัวคั่น รวมถึงคำนำหน้าและส่วนต่อท้ายสำหรับลำดับทั้งหมดได้:String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ]
-
summingInt(ToIntFunction mapper)
-
summingLong(ToLongFunction mapper)
-
summingDouble(ToDoubleFunction mapper)
- ตัวสะสมที่แปลงวัตถุเป็น int/long/double และคำนวณผลรวม
GO TO FULL VERSION