|
發表者 |
討論內容 |
冷日 (冷日) |
發表時間:2022/6/24 2:23 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [轉貼]Removing all duplicates from a List in Java
Removing all duplicates from a List in JavaLast modified: September 8, 2021 1. IntroductionIn this quick tutorial, we're going to learn how to clean up the duplicate elements from a List. First, we'll use plain Java, then Guava, and finally, a Java 8 Lambda-based solution. This tutorial is part of the “Java – Back to Basic” series here on Baeldung. 2. Remove Duplicates From a List Using Plain JavaWe can easily remove the duplicate elements from a List with the standard Java Collections Framework through a Set:
public void givenListContainsDuplicates_whenRemovingDuplicatesWithPlainJava_thenCorrect() { List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0); List<Integer> listWithoutDuplicates = new ArrayList<>( new HashSet<>(listWithDuplicates)); assertThat(listWithoutDuplicates, hasSize(5)); assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2)); }
As we can see, the original list remains unchanged. In the example above, we used HashSet implementation, which is an unordered collection. As a result, the order of the cleaned-up listWithoutDuplicates might be different than the order of the original listWithDuplicates. If we need to preserve the order, we can use LinkedHashSet instead:
public void givenListContainsDuplicates_whenRemovingDuplicatesPreservingOrderWithPlainJava_thenCorrect() { List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0); List<Integer> listWithoutDuplicates = new ArrayList<>( new LinkedHashSet<>(listWithDuplicates)); assertThat(listWithoutDuplicates, hasSize(5)); assertThat(listWithoutDuplicates, containsInRelativeOrder(5, 0, 3, 1, 2)); }
3. Remove Duplicates From a List Using GuavaWe can do the same thing using Guava as well:
public void givenListContainsDuplicates_whenRemovingDuplicatesWithGuava_thenCorrect() { List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0); List<Integer> listWithoutDuplicates = Lists.newArrayList(Sets.newHashSet(listWithDuplicates)); assertThat(listWithoutDuplicates, hasSize(5)); assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2)); }
Here also, the original list remains unchanged. Again, the order of elements in the cleaned-up list might be random. If we use the LinkedHashSet implementation, we'll preserve the initial order:
public void givenListContainsDuplicates_whenRemovingDuplicatesPreservingOrderWithGuava_thenCorrect() { List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0); List<Integer> listWithoutDuplicates = Lists.newArrayList(Sets.newLinkedHashSet(listWithDuplicates)); assertThat(listWithoutDuplicates, hasSize(5)); assertThat(listWithoutDuplicates, containsInRelativeOrder(5, 0, 3, 1, 2)); }
4. Remove Duplicates From a List Using Java 8 LambdasFinally, let's look at a new solution, using Lambdas in Java 8. We'll use the distinct() method from the Stream API, which returns a stream consisting of distinct elements based on the result returned by the equals() method. Additionally, for ordered streams, the selection of distinct elements is stable. This means that for duplicated elements, the element appearing first in the encounter order is preserved:
public void givenListContainsDuplicates_whenRemovingDuplicatesWithJava8_thenCorrect() { List<Integer> listWithDuplicates = Lists.newArrayList(5, 0, 3, 1, 2, 3, 0, 0); List<Integer> listWithoutDuplicates = listWithDuplicates.stream() .distinct() .collect(Collectors.toList()); assertThat(listWithoutDuplicates, hasSize(5)); assertThat(listWithoutDuplicates, containsInAnyOrder(5, 0, 3, 1, 2)); }
There we have it, three quick ways to clean up all the duplicate items from a List. 5. ConclusionIn this article, we demonstrated how easy it is to remove duplicates from a list using plain Java, Google Guava, and Java 8. The implementation of all of these examples and snippets can be found in the GitHub project. This is a Maven-based project, so it should be easy to import and run. 原文出處:Removing all duplicates from a List in Java | Baeldung
|
|
冷日 (冷日) |
發表時間:2022/6/24 2:15 |
- Webmaster
- 註冊日: 2008/2/19
- 來自:
- 發表數: 15771
|
- [轉貼]Java 移除 List 中重複的元素 remove duplicates from List
Java 移除List中重複的元素 remove duplicates from List Java把 List 中重複的元素移除的方法如下。 把 List 物件做為 HashSet 建構式的參數取得 HashSet 物件即可得到不重複元素的集合,因為 SET 的特性是所含的元素必須是唯一的。 List<Integer> integerList = Arrays.asList(1, 2, 2, 3, 3, 4, 4, 4, 5); Set<Integer> integerSet = new HashSet<>(integerList); System.out.println(integerSet); // [1, 2, 3, 4, 5]
或是轉為 Stream 用 distinct() 排除多的重覆。 List<Integer> integerList = Arrays.asList(1, 2, 2, 3, 3, 4, 4, 4, 5); integerList = integerList.stream().distinct().collect(Collectors.toList()); System.out.println(integerList); // [1, 2, 3, 4, 5]
若 List 的元素為自訂類別的物件則該類別必須覆寫 equals() 與 hashCode() 才有效果。 例如下面的 Order 依照 id 來區別是否相同,所以複寫 equals() 及 hashCode() 時僅利用 id 比較及計算。 Orderpackage com.abc.demo; import java.util.Objects; public class Order { private long id; // key private long amount; Order(long id, long amount) { this.id = id; this.amount = amount; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Order order = (Order) o; return id == order.id; } @Override public int hashCode() { return Objects.hash(id); } @Override public String toString() { return String.format("id=%s, amount=%s", id, amount); } }
下面建立有重覆 Order 的 List<Order> ,利用 HashSet 排除重覆的物件。 List<Order> orderList = Arrays.asList( new Order(1, 10), new Order(2, 100), new Order(2, 100), // duplicate new Order(3, 1000), new Order(3, 1000) // duplicate ); Set<Order> orderSet = new HashSet<>(orderList); System.out.println(orderSet); // [id=1, amount=10, id=2, amount=100, id=3, amount=1000]
利用 Stream.distinct() 排除重覆的物件。 List<Order> orderList = Arrays.asList( new Order(1, 10), new Order(2, 100), new Order(2, 100), // duplicate new Order(3, 1000), new Order(3, 1000) // duplicate ); orderList = orderList.stream().distinct().collect(Collectors.toList()); System.out.println(orderList); // [id=1, amount=10, id=2, amount=100, id=3, amount=1000]
若要依物件的多個非 equals() 及 hashCode() 的屬性來排除重覆,可利用 TreeSet ,其為有排序的 Set 可定義排序的規則。 例如下面的 OrderPayment 的 equals() 及 hashCode() 僅依 id 來區別是否相同。 OrderPaymentpackage com.abc.demo; import java.util.Objects; public class OrderPayment { private long id; private String orderId; private String paymentId; public OrderPayment(long id, String orderId, String paymentId) { this.id = id; this.orderId = orderId; this.paymentId = paymentId; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OrderPayment that = (OrderPayment) o; return id == that.id; } @Override public int hashCode() { return Objects.hash(id); } @Override public String toString() { return "OrderPayment{" + "id=" + id + ", orderId='" + orderId + '\'' + ", paymentId='" + paymentId + '\'' + '}'; } // getters and setters }
但下面的 List<OrderPayment> 要根據 orderId 及 paymentId 是否相同來排除重覆的元素,則在建構 TreeSet 時傳入依 orderId 結合 paymentId 的 Comparator 來比較。 List<OrderPayment> orderPaymentList = Arrays.asList( new OrderPayment(1, "H001", "C001"), new OrderPayment(1, "H001", "C001"), // duplicate new OrderPayment(2, "H001", "C002"), new OrderPayment(3, "H002", "C003"), new OrderPayment(3, "H002", "C003") // duplicate ); Set<OrderPayment> set = new TreeSet<>( Comparator.comparing(orderPayment -> orderPayment.getOrderId() + orderPayment.getPaymentId())); set.addAll(orderPaymentList); orderPaymentList = new ArrayList<>(set); System.out.println(orderPaymentList); // [OrderPayment{id=1, orderId='H001', paymentId='C001'}, OrderPayment{id=2, orderId='H001', paymentId='C002'}, OrderPayment{id=3, orderId='H002', paymentId='C003'}]
或用 Stream.collect() 搭配 TreeSet 排除多餘的重覆。 List<OrderPayment> orderPaymentList = Arrays.asList( new OrderPayment(1, "H001", "C001"), new OrderPayment(1, "H001", "C001"), // duplicate new OrderPayment(2, "H001", "C002"), new OrderPayment(3, "H002", "C003"), new OrderPayment(3, "H002", "C003") // duplicate ); orderPaymentList = orderPaymentList.stream().collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>( Comparator.comparing(orderPayment -> orderPayment.getOrderId() + orderPayment.getPaymentId() ))), ArrayList::new)); System.out.println(orderPaymentList); // [OrderPayment{id=1, orderId='H001', paymentId='C001'}, OrderPayment{id=2, orderId='H001', paymentId='C002'}, OrderPayment{id=3, orderId='H002', paymentId='C003'}]
原文出處:菜鳥工程師 肉豬: Java 移除List中重複的元素 remove duplicates from List
|
|
|