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

Java 8 Streams Tutorial พร้อมตัวอย่างโค้ด

ในบล็อกโพสต์นี้ เราจะพูดถึงฟีเจอร์ Java 8 Streams และให้ตัวอย่างโค้ดต่างๆ มากมาย

Java Streams นำการเขียนโปรแกรมเชิงฟังก์ชันมาสู่ java และได้รับการสนับสนุนโดยเริ่มใน java 8 ดังนั้นหากคุณมี java เวอร์ชันเก่า คุณต้องอัปเกรดเป็น java 8 เพื่อใช้ Java Streams

เหตุใดจึงควรใช้ Java Streams

ข้อดีบางประการของสตรีม:

  • สตรีมจะทำให้คุณเป็นโปรแกรมเมอร์ Java ที่มีประสิทธิภาพมากขึ้น (คุณจะเห็นว่าด้วยโค้ดเพียงไม่กี่บรรทัด คุณสามารถประสบความสำเร็จได้มากโดยใช้สตรีม)
  • ใช้นิพจน์แลมบ์ดาอย่างหนักซึ่งเป็นฟังก์ชันที่ใช้แล้วทิ้ง
  • ParallelStreams ช่วยให้ดำเนินการแบบมัลติเธรดสำหรับชุดข้อมูลขนาดใหญ่ได้ง่ายมาก

สตรีมไปป์ไลน์

ในกรณีส่วนใหญ่ ไปป์ไลน์สตรีมประกอบด้วย

  • ที่มา (ที่ที่ข้อมูลของคุณไหลออก)
  • ตามด้วยศูนย์หรือมากกว่า การดำเนินการระดับกลาง
  • และ การทำงานของเทอร์มินัล

Java 8 Streams Tutorial พร้อมตัวอย่างโค้ด

แหล่งที่มากำลังจะสตรีมองค์ประกอบต่างๆ

สตรีมขององค์ประกอบนั้นสามารถกรอง จัดเรียง หรือแมปหรือชุดการดำเนินการอื่น ๆ ที่ใช้กับแต่ละองค์ประกอบได้

ในตอนท้ายสามารถรวบรวมหรือลดหรือดำเนินการอื่น ๆ ของเทอร์มินัล แต่ดำเนินการเพียงเทอร์มินัลเดียวเท่านั้น

แหล่งที่มาของสตรีม

แหล่งที่มาของสตรีม สามารถมาจากคอลเล็กชัน รายการ ชุด อาร์เรย์ของ 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