Mục lục
Sắp xếp là một trong những thao tác thường xuyên trong lúc code. Java đã xây dựng sẵn các hàm sắp xếp có trong ArrayList class và Collections.
Thế nhưng hôm nay mình sẽ giới thiệu cho các bạn cách sắp xếp mới sử dụng stream api nó mạnh mẽ như thế nào.
Stream api được giới thiệu trong java 8, hỗ trợ mạnh mẽ cho chúng ta việc viết mã. Trong bài viết này, chúng ra sẽ tìm hiểu xem làm thế nào để sắp xếp ArrayList với stream api.
Syntax:
public final Stream<P_OUT> sorted(Comparator<? super P_OUT> comparator)
Sort ArrayList tăng dần với stream api
Stream cung cấp cho chúng ta method sort() trong đường ống của nó.
Ví dụ 1: Sắp xếp một ArrayList số nguyên tăng dần và xuất các phần tử ra màn hình console.
// File Main.java import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ArrayList<Integer> arr = new ArrayList<>(); arr.add(1); arr.add(-1); arr.add(99); arr.add(23); arr.add(10); arr.add(5); arr.add(4); arr.add(7); arr.add(8); List<Integer> sortArr= arr.stream() .sorted((o1, o2) -> o1 - o2) .collect(Collectors.toList()); sortArr.forEach(t -> System.out.printf(t + " ")); } }
Output: -1 1 4 5 7 8 10 23 99
Ví dụ 2: Cho một ArrayList chứa danh sách các nhân viên gồm các thông tin sau: tên, tuổi, lương. Sắp xếp ArrayList tăng dần theo tuổi.
// File Staff.java public class Staff { private String name; private double salary; private int age; public Staff(String name, double salary, int age) { this.name = name; this.salary = salary; this.age = age; } public String getName() { return name; } public double getSalary() { return salary; } public int getAge() { return age; } }
// File Main.java import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ArrayList<Staff> arr = new ArrayList<>(); arr.add(new Staff("H", 10000000, 20)); arr.add(new Staff("B", 25000000, 21)); arr.add(new Staff("F", 20000000, 30)); arr.add(new Staff("K", 15000000, 27)); arr.add(new Staff("I", 10000000, 21)); arr.add(new Staff("P", 10000000, 21)); System.out.println("Cach 1"); List<Staff> arrSort1 = arr.stream().sorted((s1, s2) -> s1.getAge() - s2.getAge()) .collect(Collectors.toList()); System.out.println(arrSort1); System.out.println("Cach 2"); List<Staff> arrSort2 = arr.stream().sorted(Comparator.comparingInt(Staff::getAge)) .collect(Collectors.toList()); System.out.println(arrSort2); } }
Output:
Cach 1
[Staff{name=’H’, salary=1.0E7, age=20}, Staff{name=’B’, salary=2.5E7, age=21}, Staff{name=’I’, salary=1.0E7, age=21}, Staff{name=’P’, salary=1.0E7, age=21}, Staff{name=’K’, salary=1.5E7, age=27}, Staff{name=’F’, salary=2.0E7, age=30}]
Cach 2
[Staff{name=’H’, salary=1.0E7, age=20}, Staff{name=’B’, salary=2.5E7, age=21}, Staff{name=’I’, salary=1.0E7, age=21}, Staff{name=’P’, salary=1.0E7, age=21}, Staff{name=’K’, salary=1.5E7, age=27}, Staff{name=’F’, salary=2.0E7, age=30}]
Sort ArrayList giảm dần với streap api
Ví dụ: Cho một ArrayList chứa danh sách các nhân viên gồm các thông tin sau: tên, tuổi, lương. Sắp xếp ArrayList giảm dần theo lương.
import java_regex.Staff; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ArrayList<Staff> arr = new ArrayList<>(); arr.add(new Staff("H", 10000000, 20)); arr.add(new Staff("B", 25000000, 21)); arr.add(new Staff("F", 20000000, 30)); arr.add(new Staff("K", 15000000, 27)); arr.add(new Staff("I", 10000000, 21)); arr.add(new Staff("P", 10000000, 21)); System.out.println("Cach 1"); List<Staff> arrSort1 = arr.stream().sorted(Comparator.comparingDouble(Staff::getSalary).reversed()) .collect(Collectors.toList()); System.out.println(arrSort1); System.out.println("Cach 2"); List<Staff> arrSort2 = arr.stream().sorted((s1, s2) -> Double.compare(s1.getSalary(), s2.getSalary())) .collect(Collectors.toList()); System.out.println(arrSort2); } }
Output:
Cach 1
[Staff{name=’B’, salary=2.5E7, age=21}, Staff{name=’F’, salary=2.0E7, age=30}, Staff{name=’K’, salary=1.5E7, age=27}, Staff{name=’H’, salary=1.0E7, age=20}, Staff{name=’I’, salary=1.0E7, age=21}, Staff{name=’P’, salary=1.0E7, age=21}]
Cach 2
[Staff{name=’H’, salary=1.0E7, age=20}, Staff{name=’I’, salary=1.0E7, age=21}, Staff{name=’P’, salary=1.0E7, age=21}, Staff{name=’K’, salary=1.5E7, age=27}, Staff{name=’F’, salary=2.0E7, age=30}, Staff{name=’B’, salary=2.5E7, age=21}]
Sort ArrayList theo nhiều thuộc tính
Sắp xếp tăng dần các Staff theo mức lương, nếu cùng mức lương tiến hàng sắp xếp theo tuổi
import java_regex.Staff; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ArrayList<Staff> arr = new ArrayList<>(); arr.add(new Staff("H", 10000000, 20)); arr.add(new Staff("B", 25000000, 21)); arr.add(new Staff("F", 20000000, 30)); arr.add(new Staff("K", 15000000, 27)); arr.add(new Staff("I", 10000000, 21)); arr.add(new Staff("P", 10000000, 21)); List<Staff> arrSort1 = arr.stream().sorted(Comparator.comparing(Staff::getSalary).thenComparing(Staff::getAge)) .collect(Collectors.toList()); System.out.println(arrSort1); } }
Output:
[Staff{name=’H’, salary=1.0E7, age=20}, Staff{name=’I’, salary=1.0E7, age=21}, Staff{name=’P’, salary=1.0E7, age=21}, Staff{name=’K’, salary=1.5E7, age=27}, Staff{name=’F’, salary=2.0E7, age=30}, Staff{name=’B’, salary=2.5E7, age=21}]
Như vậy thì chúng ta thấy việc sắp xếp ArrayList với stream api quá dễ dàng phải không nào! Bật mí luôn là ở công ty mình sắp xếp, tìm kiếm các kiểu đều sử dụng stream hết đó nha =).
Note: Các phần tử trong ArrayList các bạn lấy được từ việc sắp xếp của stream và các phần tử của ArrayList ban đầu là 1, tất là cả 2 đều trỏ đến một vùng nhớ.
Thực nghiệm
import java_regex.Staff; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { ArrayList<Staff> arr = new ArrayList<>(); arr.add(new Staff("H", 10000000, 20)); arr.add(new Staff("A", 20000000, 22)); List<Staff> arrSort1 = arr.stream().sorted(Comparator.comparing(Staff::getSalary).thenComparing(Staff::getAge)) .collect(Collectors.toList()); arrSort1.get(0).setAge(100); System.out.println(arr); System.out.println("-------------------------"); System.out.println(arrSort1); } }
Output:
[Staff{name=’H’, salary=1.0E7, age=100}, Staff{name=’A’, salary=2.0E7, age=22}]
————————-
[Staff{name=’H’, salary=1.0E7, age=100}, Staff{name=’A’, salary=2.0E7, age=22}]
Như các bạn thấy, mình lấy phần tử đầu tiên của ArrayList đã được sắp xếp và gán age = 100. Thế nhưng phần tử của ArrayList ban đầu cũng thay đổi theo.