Khi làm việc với List trong Java, đôi lúc chúng ta cần tạo 1 List các Object không trùng lặp. Bài viết này, mình sẽ hướng dẫn các bạn xóa các Object trùng lặp trong List Java.
Ở bài trước chúng ta đã làm việc với Stream, và chúng ta tiếp tục ứng dụng stream trong bài này nhé.
Ví dụ mình có các Objects sau:
Stock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Stock { OptionalDate date; StockStatus stockStatus; Boolean canRequest; public Stock(OptionalDate date, StockStatus stockStatus) { this.date = date; this.stockStatus = stockStatus; } public OptionalDate getDate() { return date; } public StockStatus getStockStatus() { return stockStatus; } public Boolean canRequest() { return canRequest; } } |
OptionalDate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class OptionalDate { LocalDate date; public OptionalDate(LocalDate date) { this.date = date; } public LocalDate date() { return date; } @Override public int compareTo(OptionalDate o) { if (date.isBefore(o.date)) return -1; if (date.isAfter(o.date)) return 1; else return 0; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OptionalDate that = (OptionalDate) o; return Objects.equals(date, that.date); } @Override public int hashCode() { return Objects.hash(date); } } |
StockStatus
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public class StockStatus { Integer value; public StockStatus(Integer value) { this.value = value; } Integer value() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; StockStatus that = (StockStatus) o; return value == that.value; } @Override public int hashCode() { return Objects.hash(value); } } |
Bây giờ, mình cần phải xóa các phần tử bị trùng lặp nhau trong List<Stock> bởi 2 Object là OptionalDate và StockStatus.
Trước tiên, chúng ta cần Override lại 2 method equals và hashCode cho 2 object này. Sau đó, mình thực hiện distinct bởi 2 object.
Chúng ta định nghĩa hàm distinct như sau:
1 2 3 4 5 6 7 8 9 10 |
private static <T> Predicate<T> distinctByKeys(Function<? super T, ?>... keyExtractors) { final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>(); return t -> { final List<?> keys = Arrays.stream(keyExtractors) .map(ke -> ke.apply(t)) .collect(Collectors.toList()); return seen.putIfAbsent(keys, Boolean.TRUE) == null; }; } |
Với hàm trên, chúng ta có thể distinct List với multiple Object.
Cuối cùng, ta dùng filter của Stream để xóa các phần tử bị trùng lặp.
1 2 3 4 |
List<Stock> stocks = list .stream() .filter(distinctByKeys(Stock::getDate, Stock::getStockStatus)) .collect(Collectors.toList()); |
Leave a Reply