menu

VanThuong.Com

Blog học lập trình Java và SEO miễn phí.

Java 8 Streams API - Cách dùng phương thức findAny, findFirst

Posted by on
Trong bài hướng dẫn này tôi sẽ giải thích về cách sử dụng 2 phương thức findAny() và findFirst() của Java 8 Streams API qua các ví dụ. Bài viết hướng dẫn này giả định rằng bạn đã quen thuộc với việc sử dụng Java 8 Streams API.
Java 8 Streams API - Cách dùng phương thức findAny, findFirst

Phương thức findAny()

Giả sử chúng ta có một đặc tả business như sau: Bất kỳ phần tử nào của Stream thỏa mãn được tiêu chí đưa ra thì có thể nhận. Có nghĩa là: một phần tử chính xác là không cần thiết, chỉ cần nó thuộc tập thỏa mãn tiêu chí đưa ra đều có thể được lấy.

Phương thức findAny() là một phương thức lý tưởng để bạn sử dụng sau khi đã filter các phần tử trong Stream với một tiêu chuẩn nhất định, và sau đó là muốn lấy ra một phần tử bất kỳ trong tập đã được lọc.

Điều quan trọng cần lưu ý là phương thức Stream.findAny() theo nghĩa đen sẽ trả về cho bạn một phần tử bất kỳ trên stream mà nó được gọi. Do đó, kết quả trả là có thể sẽ không trùng khớp khi được gọi nhiều lần trên stream.

Ngoài ra, Stream.findAny() cũng là một short-circuiting và terminal operation.

Syntax
Optional<T> findAny()
Trong đó:
- findAny() là phương thức không nhận bất kỳ đầu vào nào.
- Kết quả trả về là một Optional<T> với T là kiểu của Stream mà phương thức findAny() được gọi.

Dưới đây là đoạn code ví dụ cách dùng findAny().
com.vanthuong.java8.Person
package com.vanthuong.java8;

/**
 * Official blog: http://www.vanthuong.com
 * Learn and share your java knowledge
 */
public class Person {
  private String name;
  private Integer age;

  public Person(String name, Integer age) {
    this.name = name;
    this.age = age;
  }

  // Getters and setters for name and age go here
  // Override equals() and hasCode() go here
  
  @Override
  public String toString() {
    return "Person{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
  }

}

com.vanthuong.java8.FindInStreamExample
package com.vanthuong.java8;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Official blog: http://www.vanthuong.com
 * Learn and share your java knowledge
 */
public class FindInStreamExample {
  public static void main(String[] args) {
    List<Person> persons = initListOfPersons();
    Optional<Person> anyPersonAbove40 = persons
        .stream()
        .filter(person -> person.getAge() > 40)
        .findAny();

    if (anyPersonAbove40.isPresent()) {
      System.out.println("Any person above age 40: " + anyPersonAbove40.get());
    }
  }

  private static List initListOfPersons() {
    List<Person> persons = new ArrayList&glt;>();
    persons.add(new Person("Nguyen Van A", 30));
    persons.add(new Person("Nguyen Thi B", 35));
    persons.add(new Person("Tran Van C", 33));
    persons.add(new Person("Do Thi Thu D", 20));
    persons.add(new Person("Tran Thi Tuyet E", 23));
    persons.add(new Person("Ly Tan F", 44));
    persons.add(new Person("Hoang Ngoc G", 19));
    persons.add(new Person("Luu Nhat H", 65));
    persons.add(new Person("Doan Chinh I", 45));
    return persons;
  }
}

Biên dịch và chạy chương trình sẽ in ra kết quả sau:
Any person above age 40: Person{name='Ly Tan F', age=44}

OK, để giải thích về đoạn code trên chút xíu ha
+ Person class được định nghĩa với 2 thuộc tính là nameage
+ FindInStreamExample class đã tạo bao gồm phương thức initListOfPersons() để trả về một danh sách các đối tượng Person
+ Trong phương thức main() của FindInStreamExample, chúng ta đang convert persons (List of persons) sang stream để filter xem có bất kỳ Person nào có age > 40 hay không.
+ Khi stream đã được filter rồi thì chúng ta gọi phương thức findAny() để trả về một Option<Person> cho biến anyPersonAbove40.
+ Sau khi sử dụng phương thức isPresent() để check xem Optional có giá trị hay không thì chúng ta gọi phương thức get() của Optional và in nó ra màn hình.
+ Output chúng ta có được là Ly Tan F, 44 tuổi. Đây là đối tượng Person mà chúng ta có được khi gọi findAny()

Phương thức findFirst()

Khi chúng ta có một đặc tả business yêu cầu lấy phần tử đầu tiên của stream sau khi đã filter (lọc) theo một tiêu chí nào đó thì đây là phương thức mà chúng ta có sử dụng.
Syntax
Optional<T> findFirst()
Trong đó:
- findFirst() không nhận paramter đầu vào
- Kết quả trả về là một Optional<T> với T là kiểu dữ liệu của Stream đã gọi gọi phương thức findFirst().

Chúng ta sẽ sử dụng lại đoạn code ví dụ ở trên và chỉ chỉnh sửa lại chút xíu trong hàm main() của FindInStreamExample class như sau:
public static void main(String[] args) {
  List<Person> persons = initListOfPerson();
  Optional firstPersonBelow30 = persons
      .stream()
      .filter(person -> person.getAge() < 30)
      .findFirst();

  if (firstPersonBelow30.isPresent()) {
    System.out.println("First person below age 30: " + firstPersonBelow30.get());
  }
}

Biên dịch và chạy lại chương trình các bạn sẽ được kết quả như sau:
First person below age 30: Person{name='Do Thi THu D', age=20}

Cũng tương tự như ví dụ về cách dùng findAny() thì đoạn code trên được chúng ta thay đổi để filter ra những Person có tuổi < 30. Khi gọi phương thức findFirst() trên stream đã được filter thì nó sẽ trả về cho chúng ta kết quả đầu tiên chính là Person{name='Do Thi THu D', age=20}
Đăng bình luận

menu