Computer >> Máy Tính >  >> Lập trình >> Java

Hướng dẫn Java 8 Streams với các ví dụ về mã

Trong bài đăng trên blog này, chúng ta sẽ thảo luận về các tính năng của Java 8 Streams và cung cấp nhiều ví dụ mã khác nhau.

Java Streams mang đến lập trình chức năng cho java và chúng được hỗ trợ bắt đầu từ java 8, nếu bạn có phiên bản java cũ hơn, thì bạn phải nâng cấp lên java 8 để sử dụng Java Streams.

Tại sao sử dụng Java Streams?

Một số ưu điểm của luồng:

  • Luồng sẽ giúp bạn trở thành một lập trình viên java hiệu quả hơn (bạn sẽ thấy rằng với rất ít dòng mã, bạn thực sự có thể đạt được khá nhiều điều khi sử dụng luồng).
  • Họ sử dụng nhiều các biểu thức lambda, một loại hàm dùng một lần.
  • ParallelStreams cho phép các hoạt động đa luồng đối với các tập dữ liệu lớn rất dễ dàng.

Đường ống Luồng

Trong hầu hết các trường hợp, một đường dẫn luồng bao gồm một

  • nguồn (nơi dữ liệu của bạn chảy ra ngoài)
  • theo sau là không hoặc nhiều hoạt động trung gian
  • và một thao tác đầu cuối

Hướng dẫn Java 8 Streams với các ví dụ về mã

Nguồn sẽ truyền một luồng các phần tử.

Luồng các phần tử đó có thể được lọc, sắp xếp hoặc nó có thể được ánh xạ hoặc các chuỗi hoạt động khác được áp dụng cho từng phần tử.

Cuối cùng, nó có thể được thu thập hoặc giảm bớt hoặc một số thao tác đầu cuối khác nhưng chỉ một thao tác đầu cuối được thực hiện.

Nguồn Luồng

Nguồn luồng có thể đến từ các tập hợp, danh sách, tập hợp, mảng int, longs, double, string, v.v.

Hoạt động Luồng

Hoạt động truyền trực tuyến là trung gian hoặc thiết bị đầu cuối:

  • Hoạt động trung gian chẳng hạn như bộ lọc, bản đồ hoặc sắp xếp trả về một luồng để chúng tôi có thể xâu chuỗi nhiều hoạt động trung gian.
  • Hoạt động của thiết bị đầu cuối nhận một luồng và chúng có thể trả về giá trị vô hiệu hoặc chúng có thể trả về kết quả không phải là luồng, chẳng hạn như giảm, ví dụ:giảm các mục vào một danh sách.

Hoạt động Trung gian

  • Không cho phép hoặc nhiều thao tác trung gian.
  • Vấn đề đặt hàng; đối với tập dữ liệu lớn: lọc trước sau đó sắp xếp hoặc lập bản đồ.
  • Đối với những tập dữ liệu rất lớn, chúng tôi ParallelStream để kích hoạt nhiều chuỗi.

Một số hoạt động trung gian bao gồm:

  • anyMatch ()
  • riêng biệt ()
  • bộ lọc ()
  • findFirst ()
  • bản đồ phẳng ()
  • bản đồ ()
  • bỏ qua ()
  • đã sắp xếp ()

Hoạt động đầu cuối

Chỉ được phép sử dụng một thao tác đầu cuối.

  • forEach áp dụng cùng một chức năng cho từng phần tử, chẳng hạn như in từng phần tử.
  • thu thập lưu tất cả các phần tử vào một tập hợp hoặc một danh sách hoặc một mảng.
  • tất cả các tùy chọn khác đều giảm luồng thành một phần tử tóm tắt duy nhất.

Một số ví dụ về hàm giảm là:

  • count ()
  • max ()
  • phút ()
  • giảm bớt ()

Ví dụ về mã luồng Java

Bây giờ chúng ta hãy xem các khái niệm trên trong các ví dụ mã.

Luồng số nguyên

Ví dụ đầu tiên chỉ là một luồng số nguyên. Chúng tôi sẽ tạo một luồng số nguyên bằng cách sử dụng IntStream lớp và hàm phạm vi của nó cung cấp cho chúng ta một phạm vi số nguyên.

forEach là hoạt động đầu cuối của chúng tôi. Đối với mỗi mục, chúng tôi sẽ in nó ra.

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();
    }
}

Đầu ra:

123456789

Luồng số nguyên có Bỏ qua

Ví dụ thứ hai sử dụng một luồng số nguyên nhưng chúng tôi đã thêm một skip() ở đây, vì vậy trong trường hợp này, chúng tôi sẽ bỏ qua 5 yếu tố đầu tiên trong luồng của chúng tôi.

Điều này sẽ chỉ in các phần tử từ 6 đến 9. Chúng tôi cũng đang sử dụng một biểu thức lambda đơn giản để in mục

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();
    }
}

Đầu ra:

6
7
8
9

Luồng Số nguyên với Tổng

Ví dụ thứ ba, chúng tôi lại sử dụng IntStream Tuy nhiên, để tạo luồng đối tượng của chúng tôi, chúng tôi đặt nó bên trong println() câu lệnh làm tham số cho dòng in.

Những gì chúng ta sẽ in chỉ là tổng từ phạm vi 1 đến 5, nói cách khác, 1 2 3 &4 sẽ chỉ in ra tổng của những số đó:

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();
    }
}

Đầu ra:

10

Stream.of

Ví dụ tiếp theo sử dụng Stream.of , điều này thực sự tiện dụng vì bạn có thể truyền trực tuyến số nguyên, giá trị dấu phẩy động hoặc chuỗi hoặc thậm chí các đối tượng.

Trong ví dụ này, chúng ta chỉ sắp xếp theo thứ tự bảng chữ cái thẳng sau đó chúng ta sẽ tìm mục đầu tiên bằng cách sử dụng findFirst() hàm số. Sau đó, chúng tôi chỉ in ra mục đầu tiên trong danh sách.

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);
    }
}

Đầu ra

Alberto

Truyền từ Mảng, sắp xếp, lọc và in

Trong ví dụ tiếp theo, chúng ta sẽ phát trực tiếp từ một mảng. Sau đó, chúng tôi sẽ sắp xếp, lọc và sau đó in.

Ở đây, chúng tôi sẽ chỉ lọc ra các mục bắt đầu bằng s .

Chúng tôi sử dụng biểu thức lambda nhận X đó là từng tên và sau đó nó kiểm tra những tên nào bắt đầu bằng ký tự s và nó sẽ chuyển những điều đó.

Sau đó, chúng tôi sẽ sắp xếp chúng và sau đó đối với mỗi mục vượt qua phân loại đó, chúng tôi sẽ in nó.

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);
    }
}

Đầu ra:

Sarah
Sarika
Shivika

Mức trung bình của Mảng Số nguyên

Bây giờ chúng ta hãy xem cách chúng ta có thể lấy giá trị trung bình của squaresof một mảng int.

Ở đây, chúng tôi sử dụng Arrays.stream() hàm để truyền các số nguyên và sau đó chúng ta sẽ sử dụng map() để ánh xạ từng mục, từng số nguyên thành hình vuông của nó.

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);
    }
}

Đầu ra:

44.0

Lưu ý rằng nó sẽ in ra gấp đôi thay vì một số nguyên.

Luồng từ Danh sách, lọc và in

Trong ví dụ này, chúng tôi sẽ phát trực tuyến từ một danh sách, lọc các mục đó và sau đó in.

Lưu ý rằng trong map() , chúng tôi sẽ chuyển đổi tất cả các tên thành chữ thường.

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);
    }
}

Đầu ra:

al
ankit
amanda

Có thể thấy chúng ta có ba tên bắt đầu bằng a và chúng đều là chữ thường.

Truyền các hàng từ tệp văn bản, sắp xếp, lọc và in

Trong ví dụ tiếp theo của chúng tôi, chúng tôi sẽ truyền trực tuyến các hàng từ một tệp văn bản. Chúng tôi sẽ sắp xếp, lọc và in.

Giả sử chúng ta có một tệp có tên là bands.txt với nội dung hiển thị bên dưới:

Rolling Stones
Lady Gaga
Jackson Browne
Maroon 5
Arijit Singh
Elton John
John Mayer
CCR
Eagles
Pink
Aerosmith
Adele
Taylor Swift

Chúng tôi sẽ sử dụng Files.lines() để tạo luồng của chúng tôi, luồng này sẽ cung cấp cho chúng ta một luồng một chuỗi cho mỗi dòng của tệp.

Khi chúng tôi có luồng của mình, chúng tôi sẽ sắp xếp chúng và chúng tôi sẽ lọc ra các mục lớn hơn 13 ký tự và sau đó in các mục còn lại.

Cuối cùng, chúng tôi phải đóng tệp để chúng tôi thực hiện 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();
    }
}

Đầu ra:

Jackson Browne
Rolling Stones

Chúng tôi nhận được hai dải có hơn 13 ký tự.

Truyền các hàng từ tệp văn bản và lưu vào Danh sách

Đối với ví dụ này, chúng tôi sẽ sử dụng cùng một tệp văn bản như trên.

Chúng tôi muốn lọc ra các mục có chứa các ký tự jit , sử dụng x.contains() chỉ là một hàm chuỗi.

Sử dụng .collect() chúng tôi thêm tất cả những cái có chữ cái jit vào một danh sách.

Khi chúng tôi có danh sách, sau đó chúng tôi có thể sử dụng forEach toán tử để in các mục.

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));
    }
}

Đầu ra:

Arijit Singh

Truyền trực tuyến các hàng từ tệp CSV và đếm

Trong ví dụ này, chúng tôi truyền trực tuyến các hàng từ tệp CSV và chúng tôi sẽ đếm các hàng tốt.

Giả sử chúng ta có một tệp có tên là data.txt với các nội dung sau:

A,12,3.7
B,17,2.8
C,14,1.9
D,23,2.7
E
F,18,3.4

Ở đây, hàng E không có dữ liệu, vì vậy chúng tôi muốn loại trừ hàng đó khỏi luồng của mình.

Trong đoạn mã sau, chúng ta sẽ đọc trong mỗi hàng, sau đó chúng ta cần tách các dấu phẩy thành một mảng để mỗi hàng sẽ trở thành một mảng các mục.

Sau đó, chúng tôi áp dụng bộ lọc để lọc ra các hàng không có ba mục.

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();
    }
}

Đầu ra:

5 rows

Giảm - tổng

Ví dụ này cho bạn thấy làm thế nào để sử dụng giảm. Chúng tôi sẽ giảm xuống một tổng. Ở đây, chúng ta có một luồng kép bằng cách sử dụng Stream.of() hàm số. Chúng tôi đã xác định ba giá trị nhân đôi trong ba đối số khác nhau và chúng tôi sẽ sử dụng hàm giảm.

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);
    }
}

Đầu ra:

13.600000000000001