Loại bỏ các phần tử trùng trong một ArrayList như thế nào trong Java 8?
Bài viết được sự cho phép của tác giả Giang Phan
Trong bài viết Loại bỏ các phần tử trùng trong một ArrayList , tôi đã giới thiệu với các bạn các cách để loại bỏ phần tử trùng trong một ArrayList với Java <= 7. Trong bài này, tôi sẽ giới thiệu với các bạn một số cách khác với sự hỗ trợ của các tính năng mới trong Java 8.
Sử dụng phương thức distinct() trong Stream API
Phương thức distinct() trả về một Stream gồm các phần tử duy nhất, việc xác định các phần tử trùng lặp được so sánh theo theo phương thức Object.equals(Object).
Đối với ordered Stream, thứ tự sắp xếp các phần tử là ổn định (stable) : đối với các phần tử trùng lặp, phần tử xuất hiện đầu tiên trong vùng gặp phải được giữ nguyên.
Đối với các unordered Stream, không đảm bảo tính ổn định (unstable) thứ tự các phần tử.
Ví dụ:
package com.gpcoder.remove_duplicate; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class RemoveDuplicateInArrayList1 { public static void main(String[] args) { List listWithDuplicateElements = new ArrayList(); listWithDuplicateElements.add("JAVA"); listWithDuplicateElements.add("J2EE"); listWithDuplicateElements.add("JSP"); listWithDuplicateElements.add("SERVLETS"); listWithDuplicateElements.add("JAVA"); listWithDuplicateElements.add("STRUTS"); listWithDuplicateElements.add("JSP"); List listWithoutDuplicateElements = listWithDuplicateElements .stream() .distinct() .collect(Collectors.toList()); System.out.println(listWithoutDuplicateElements); // [JAVA, J2EE, JSP, SERVLETS, STRUTS] } }
Sử dụng phương thức removeIf()
Phương thức removeIf() : chấp nhận đối số là 1 Predicate, nó loại bỏ tất cả các phần tử của Collection thỏa mãn điều kiện đã cho.
Ý tưởng cách này là lợi dụng tính năng không chứa phần tử trùng của HashSet/ LinkedHashSet để kiểm tra tồn tại và loại bỏ phần nó.
Ví dụ:
package com.gpcoder.remove_duplicate; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class RemoveDuplicateInArrayList2 { public static void main(String[] args) { List listWithDuplicateElements = new ArrayList(); listWithDuplicateElements.add("JAVA"); listWithDuplicateElements.add("J2EE"); listWithDuplicateElements.add("JSP"); listWithDuplicateElements.add("SERVLETS"); listWithDuplicateElements.add("JAVA"); listWithDuplicateElements.add("STRUTS"); listWithDuplicateElements.add("JSP"); Set elementsAlreadySeen = new LinkedHashSet<>(); listWithDuplicateElements.removeIf(s -> !elementsAlreadySeen.add(s)); System.out.println(elementsAlreadySeen); // [JAVA, J2EE, JSP, SERVLETS, STRUTS] } }
Sử dụng phương thức collect() với Collectors.toCollection
Phương thức collect() chấp nhận đối số là một Collector. Trong Java 8, chúng ta có thể sử dụng phương thức Collectors.toCollection() để tạo ra Collector. Phương thức này, chấp nhận đối số là Supplier. Ý tưởng cách này cũng là lợi dụng tính năng không chứa phần tử trùng của HashSet/ LinkedHashSet / TreeSet.
Ví dụ bên dưới dùng để loại bỏ các sinh viên có cùng email với TreeSet.
package com.gpcoder.remove_duplicate; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; class Student { private String name; private String email; public Student(String name, String email) { super(); this.name = name; this.email = email; } public String getName() { return name; } public String getEmail() { return email; } @Override public String toString() { return "Student [name=" + name + ", email=" + email + "]"; } } public class RemoveDuplicateInArrayList3 { public static void main(String[] args) { List studentsWithtDuplicate = new ArrayList<>(); studentsWithtDuplicate.add(new Student("Nguyen Nhat", "[email protected]")); studentsWithtDuplicate.add(new Student("Le Van", "[email protected]")); studentsWithtDuplicate.add(new Student("Tran Khoa", "[email protected]")); studentsWithtDuplicate.add(new Student("Le Vo", "[email protected]")); studentsWithtDuplicate.add(new Student("Ly Nguyen", "[email protected]")); Set studentsWithoutDuplicate = studentsWithtDuplicate.stream() .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getEmail)))); studentsWithoutDuplicate.forEach(s -> System.out.println(s)); } }
Output của chương trình:
Student [name=Le Van, [email protected]] Student [name=Ly Nguyen, [email protected]] Student [name=Nguyen Nhat, [email protected]] Student [name=Tran Khoa, [email protected]]
Trong thực tế, người ta thường sử dụng phương thức distinct() để loại phần tử trùng. Sử dụng removeIf() hay collect() không tốt về performance so với distinct() và nó trả về một Set thay vì List như mong muốn, cần phải chuyển Set sang List. Tuy nhiên trong một số trường hợp chúng ta cũng có thể sử dụng cách này, nên tôi cũng giới thiệu với các bạn để thêm lựa chọn khi sử dụng.
Bài viết gốc được đăng tải tại gpcoder.com
Có thể bạn quan tâm:
- JavaScript Tips – Những điều có thể hay trong JS (P1)
- Một vài ghi chép về lệnh Iterator trong JavaScript
- 5 cách chia một mảng lớn thành nhiều mảng nhỏ trong Javascript
Xem thêm Việc làm java hấp dẫn trên TopDev
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- i iOS 18 có gì mới? Có nên cập nhật iOS 18 cho iPhone của bạn?
- G Gamma AI là gì? Cách tạo slide chuyên nghiệp chỉ trong vài phút
- P Power BI là gì? Vì sao doanh nghiệp nên sử dụng PBI?
- K KICC HCMC x TOPDEV – Bước đệm nâng tầm sự nghiệp cho nhân tài IT Việt Nam
- T Trello là gì? Cách sử dụng Trello để quản lý công việc
- T TOP 10 SỰ KIỆN CÔNG NGHỆ THƯỜNG NIÊN KHÔNG NÊN BỎ LỠ
- T Tìm hiểu Laptop AI – So sánh Laptop AI với Laptop thường
- M MySQL vs MS SQL Server: Phân biệt hai RDBMS phổ biến nhất
- S SearchGPT là gì? Công cụ tìm kiếm mới có thể đánh bại Google?