[Java 8] Sử dụng Streams filter để lọc dữ liệu

Chào các bạn, hôm nay chúng ta sẽ cùng tìm hiểu về Java 8 Streams filter(), collect(), findAny() and orElse()

1. Streams filter() và collect()
1.1 Trước Java 8, lọc các phần tử trong List như sau

BeforeJava8.java
Java:
package com.mkyong.java8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BeforeJava8 {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");
        List<String> result = getFilterOutput(lines, "mkyong");
        for (String temp : result) {
            System.out.println(temp);    //output : spring, node
        }

    }

    private static List<String> getFilterOutput(List<String> lines, String filter) {
        List<String> result = new ArrayList<>();
        for (String line : lines) {
            if (!"mkyong".equals(line)) { // we dont like mkyong
                result.add(line);
            }
        }
        return result;
    }

}
Kết quả
Code:
spring
node
1.2 Biểu thức tương đương trong Java 8, sử dụng stream.filter() để lọc phần tử trong List, và collect() để chuyền 1 stream thành List

NowJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class NowJava8 {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");

        List<String> result = lines.stream()                // convert list to stream
                .filter(line -> !"mkyong".equals(line))     // we dont like mkyong
                .collect(Collectors.toList());              // collect the output and convert streams to a List

        result.forEach(System.out::println);                //output : spring, node

    }

}
Kết quả
Code:
spring
node
2. Streams filter(), findAny() và orElse()

Person.java
Java:
package com.mkyong.java8;

public class Person {

    private String name;
    private int age;

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

    //gettersm setters, toString
}
2.1 Trước Java 8, để lọc ra object Person thông qua tên, ta sử dụng cách

BeforeJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.List;

public class BeforeJava8 {

    public static void main(String[] args) {

        List<Person> persons = Arrays.asList(
                new Person("mkyong", 30),
                new Person("jack", 20),
                new Person("lawrence", 40)
        );

        Person result = getStudentByName(persons, "jack");
        System.out.println(result);

    }

    private static Person getStudentByName(List<Person> persons, String name) {

        Person result = null;
        for (Person temp : persons) {
            if (name.equals(temp.getName())) {
                result = temp;
            }
        }
        return result;
    }
}
Kết quả
Code:
Person{name='jack', age=20}
2.2 Code tương đương trong Java 8, sử dụng stream.filter() để lọc phần từ trong List, và .findAny().orElse (null) để trả về phần tử thỏa điều kiện.

NowJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.List;

public class NowJava8 {

    public static void main(String[] args) {

        List<Person> persons = Arrays.asList(
                new Person("mkyong", 30),
                new Person("jack", 20),
                new Person("lawrence", 40)
        );

        Person result1 = persons.stream()                        // Convert to steam
                .filter(x -> "jack".equals(x.getName()))        // we want "jack" only
                .findAny()                                      // If 'findAny' then return found
                .orElse(null);                                  // If not found, return null

        System.out.println(result1);
       
        Person result2 = persons.stream()
                .filter(x -> "ahmook".equals(x.getName()))
                .findAny()
                .orElse(null);

        System.out.println(result2);

    }

}
Kết quả
Code:
Person{name='jack', age=20}
null
2.3 Trường hợp lọc với nhiều điều kiện

NowJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.List;

public class NowJava8 {

    public static void main(String[] args) {

        List<Person> persons = Arrays.asList(
                new Person("mkyong", 30),
                new Person("jack", 20),
                new Person("lawrence", 40)
        );

        Person result1 = persons.stream()
                .filter((p) -> "jack".equals(p.getName()) && 20 == p.getAge())
                .findAny()
                .orElse(null);

        System.out.println("result 1 :" + result1);

        //or like this
        Person result2 = persons.stream()
                .filter(p -> {
                    if ("jack".equals(p.getName()) && 20 == p.getAge()) {
                        return true;
                    }
                    return false;
                }).findAny()
                .orElse(null);

        System.out.println("result 2 :" + result2);

    }
}
Kết quả
Code:
result 1 :Person{name='jack', age=20}
result 2 :Person{name='jack', age=20}
3. Streams filter() và map()

NowJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class NowJava8 {

    public static void main(String[] args) {

        List<Person> persons = Arrays.asList(
                new Person("mkyong", 30),
                new Person("jack", 20),
                new Person("lawrence", 40)
        );

        String name = persons.stream()
                .filter(x -> "jack".equals(x.getName()))
                .map(Person::getName)                        //convert stream to String
                .findAny()
                .orElse("");

        System.out.println("name : " + name);

        List<String> collect = persons.stream()
                .map(Person::getName)
                .collect(Collectors.toList());

        collect.forEach(System.out::println);

    }
   
}
Kết quả
Code:
name : jack

mkyong
jack
lawrence

Cám ơn các bạn đã theo dõi. Hẹn gặp lại các bạn trong các bài viết sau :)

Bài viết tham khảo tại: https://mkyong.com/java8/java-8-streams-filter-examples
 
Sửa lần cuối:

Bình luận

Joe

Thành viên VIP
21/1/13
2,732
1,255
113
It's nice to read the "newfangled" programming techniques. But as I've already said in "Programming basics" that NOT every new technique is the best, it could confuse a lot to those who are NOT adept or experienced. Mkyong's Example:

PHP:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BeforeJava8 {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");
        List<String> result = getFilterOutput(lines, "mkyong");
        for (String temp : result) {
            System.out.println(temp);    //output : spring, node
        }

    }

    private static List<String> getFilterOutput(List<String> lines, String filter) {
        List<String> result = new ArrayList<>();
        for (String line : lines) {
            if (!"mkyong".equals(line)) { // we dont like mkyong
                result.add(line);
            }
        }
        return result;
    }

}
This little example is awkward and amateurish. Only inexperienced newbies write such an app. Otherwise it should be as following:
PHP:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test9 {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");

        List<String> result = new ArrayList<>();
        for (String temp : lines) if (!"mkyong".equals(temp)) result.add(temp);

        result.forEach(System.out::println);
    }
}
Or all with forEach with LambdaExpression
PHP:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Test9 {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");
        List<String> result = new ArrayList<>();
        lines.forEach(line -> {
            if (!"mkyong".equals(line)) result.add(line);
        });
        //for (String temp : lines) if (!"mkyong".equals(temp)) result.add(temp);
        result.forEach(System.out::println);
    }
}
Compared to the newfangled stream-filter of Mr. mkyong it's still clearer and does NOT obfuscate the processing which could be very hard to debug if there were some bugs :
PHP:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Test9a {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("spring", "node", "mkyong");

        List<String> result = lines.stream()                // convert list to stream
                .filter(line -> !"mkyong".equals(line))     // we dont like mkyong
                .collect(Collectors.toList());              // collect the output and convert streams to a List

        result.forEach(System.out::println);                //output : spring, node
    }
}
Further: a trivial thing which can be a big headache when the small things become numerous.
Code:
C:\links\java\Test>dir .\classes\Test9*.*


18.02.2020  11:18             1.516 Test9.class
18.02.2020  11:16             1.769 Test9a.class


C:\links\java\Test>
In some cases the conventional way is far-better than the newfangled technique.
 
Sửa lần cuối:

quydtkt

Administrator
1/11/19
135
14
18
26
In my opinion, when programming languages are upgraded, programmers will receive many benefits, they will save a lot of effort to create software. Of course, for beginners, you should still use the basic syntax.
Example of my friend. He is an android programmer. He often complains about java (currently the java version used for programming on android is just java 7, I can't remember clearly either). And now he has switched to using kotlin for programming =)).
 

Joe

Thành viên VIP
21/1/13
2,732
1,255
113
In my opinion, when programming languages are upgraded, programmers will receive many benefits, they will save a lot of effort to create software. Of course, for beginners, you should still use the basic syntax.
Example of my friend. He is an android programmer. He often complains about java (currently the java version used for programming on android is just java 7, I can't remember clearly either). And now he has switched to using kotlin for programming =)).
Nope. Maybe you confuse programming technique with programming abridgment. Nothing to do with programming language technology. It depends on case to case how and when one use the short-cutting and why one has to use the conventional way. If you are adept in compiler technology you will understand what I say. Just try to implement the 3 steps: stream(), filter() and collect() then you will see that the implementation is just an obfuscation of 3 basic steps: create, comparison and a loop. Another example: some developers ask for help about setting or using IDE because they are helpless without an IDE. An IDE is an editor, a repository and some AI algorithm that takes over the thinking process of its users (or developers) and that is the danger that its users (or developers) become bad coders -not as developers. It's the question of the HOW: USING or DEVELOPING. It is NOT the question of WHY or WHY-NOT.

About your friend I have only a pity. Kotlin is a cover upon JAVA or in other words: a deviation of Java. A good developer is a developer who sees a Programming Language just as a working TOOL. He is probably helpless without IDE and couldn't understand the purpose of IT development. In my interview with applicants who applied to my company I never asked about his knowledge in any Framework/Database, for example, SPRING or MongoDB, but about his knowledge in DB Technology (e.g. advantages and disadvantages of Relational DB) or in Compiler Technology (e.g. how to create a foolproof Singleton object in C# or JAVA or PYTHON).

Sorry for my comment. I'll abstain in future from my comment.
 
Sửa lần cuối:
  • Wow
Reactions: quydtkt

quydtkt

Administrator
1/11/19
135
14
18
26
Are you trying to mention the performance of the software?