lambda實體屬性去重,對實體的某個屬性進行去重

下面我將介紹一下如何爲一個List<People> 這樣的List裏面的某個屬性進行去重。順便介紹一下兩個實體之間如何用lambda進行復制
OK,我們先來寫一個Person實體

package com.dzy.test.lambda;

/**
 * Created by itar
 */
public class Person {
    private int age;
    private String name;
    private String country;
    private String address;
    private String phone;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", country='" + country + '\'' +
                ", address='" + address + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

然後寫一個會被複制的People實體,其實這種情況很常見,一般就是從數據庫種拿到的entity然後複製到dto中

package com.dzy.test.lambda;

/**
 * Created by itar
 */
public class People {
    private int age;
    private String name;
    private String country;
    private String address;
    private String phone;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "People{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", country='" + country + '\'' +
                ", address='" + address + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

主要的測試類:

package com.dzy.test.lambda;

import org.junit.Test;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Created by itar
 */
public class TestPeopleLambda {

    private static List<Person> personList=new ArrayList<>();

    static {
        for (int i = 1; i <= 20; i++) {
            Person person=new Person();
            person.setAge(i);
            person.setName("xiaoming"+i);
            //待會兒篩選屬性用到
            if (i%10==0){person.setAddress("shanghai10村");}else{
                person.setAddress("shanghai"+i+"村");
            }
            person.setCountry("中國"+i+"區");
            personList.add(person);
        }
    }


    @Test
    public void testLambda(){
        //下面我要將personList轉化爲peoplelist裏面去,少一個或者多一個屬性,看下我怎麼做
        List<People> peopleList = personList.stream().map(person -> {
            People people = new People();
            BeanUtils.copyProperties(person, people);
            return people;
            //下面我做個工作,將shanghai 10村的人合併到一起,也就是說最終會輸出17個人people,看看
        }).filter(distinctByKey(People::getAddress)).collect(Collectors.toList());

        //打印出來的實體只有19個,說明我們篩選成功了,而且成功轉成了people實體了
        peopleList.forEach(System.out::println);
    }

    /**
     * 定義一個過濾器進行去重
     * 不涉及到共享變量,沒有線程安全問題
     * 爲什麼是這樣寫的,因爲上面的filter是需要一個Predicate返回的參數的
     * 用concurrentHashMap裏面的putIfAbsent進行排重
     */
    public static<T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
    }
}

到這裏,我們的去重工作就完成了,主要起作用的是distinctByKey 這個方法的使用和編寫,本例中僅僅作用於address,還可以定製一些其他的,可以繼續filter,添加第二個去重的要求。

over!

方法2

2018年添加方法2

List<Person> distinctList = personList.stream().collect(
                    Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getName()))),
                            ArrayList::new));

主要是利用了collectingAndThen 這個方法,第二種方法比較簡便

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章