用Collectors對List去重

在學習本篇以前,最好對java8新特性有必定的瞭解。能夠參考:Java8新特性--流(Stream)html

場景:有一個實體的List集合,須要根據實體中的某個字段對List去重java

 

要想去重,能夠考慮使用TreeSet。先來看看TreeSet的用法:post

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Dish {
    
    private String id;
    
    private String name;

}
   private static List<Dish> dishList = new ArrayList<Dish>();

    static {
        Dish dish1 = new Dish("001", "張三");
        dishList.add(dish1);
        Dish dish2 = new Dish("001", "李四");
        dishList.add(dish2);
        Dish dish3 = new Dish("002", "王五");
        dishList.add(dish3);
    }
    /**
     * 測試TreeSet默認比較器及傳入比較器
     */
    @Test
    public void testTreeSet() {
        // TreeSet不傳比較器,則默認按照天然順序排序
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(3);
        treeSet.add(1);
        treeSet.add(4);
        System.out.println(treeSet);
        // [1, 3, 4]

        // TreeSet中的元素,若是是實體,必須得傳比較器(或者實體類須要實現Comparable中的compareTo方法),否則就會報錯
        // TreeSet是Set的子類,裏面的元素有序且不能重複,能夠去重
        TreeSet<Dish> treeSet2 = new TreeSet<>(Comparator.comparing(Dish::getId));
        treeSet2.addAll(dishList);
        treeSet2.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
        // id:001, name:張三
        // id:002, name:王五
    }

從上面能夠看到TreeSet能夠根據實體中的某個字段(這裏是id)排序後去重。若是再將TreeSet轉爲List就能夠達到咱們的目的:學習

     List<Dish> newDishList = new ArrayList<>(treeSet2);
        newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
        // id:001, name:張三
        // id:002, name:王五

 

雖然大功告成,可是寫這麼一堆代碼,好麻煩。能夠使用java8中的收集器簡化一下:測試

  /**
     * 測試Collectors.toCollection方法:將結果收集到其它類型的集合中(這裏是TreeSet)
     */
    @Test
    public void testToCollection() {
        TreeSet<Dish> treeSet2 = dishList.stream()
                .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Dish::getId))));
        List<Dish> newDishList = new ArrayList<>(treeSet2);
        newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
        // id:001, name:張三
        // id:002, name:王五
    }

還能夠再簡單一點:url

  /**
     * 測試Collectors.collectingAndThen方法:將流中的數據經過Collector計算,計算的結果再經過Function處理一下
     * (這裏是將TreeSet轉爲ArrayList。即至關於將最終結果又通過了new ArrayList<>(treeSet))
     */
    @SuppressWarnings("unchecked")
    @Test
    public void testCollectingAndThen() {
        List<Dish> newDishList = dishList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Dish::getId))), ArrayList::new));
        newDishList.forEach(d -> System.out.println("id:" + d.getId() + ", name:" + d.getName()));
        // id:001, name:張三
        // id:002, name:王五
    }
相關文章
相關標籤/搜索