List去重与equals/hashcode

List去重:
stackflow上关于list去除重复对象是否要重写equals和hashcode方法有争议;有的人认为重写这两个方法是具有侵入性的,有的人认为重写此二者使工作更明确的最佳实践(https://developer.jboss.org/wiki/EqualsandHashCode).有待研究.

使用set来为List去重的原理是利用set中元素不重复的特征,那使用Set来去重List中重复的Javabean一定复写此JavaBean的equals和hashcode方法吗?答案是否定的,为什么要重写equals和hashcode来去重,是因为原始的Object的equals的底层其实就是==,如果不重写equals,那么只要是new出来的bean,他们物理地址都是不同的.如果想要按照javabean中属性存在不同作为区分两者是否是重复元素的标准,那么未被复写的继承自Object的equals方法范围太大了,不够细致,所以要重写equals方法.
之所以重写equals时一般都要重写hashcode是为了提高大量对象是否重复时判断的效率,如果不重写hashcode,那就只有依次在对象见使用equals比较;重写hashcode 大大减少了比较的次数,效率提升.如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的。
对于两个对象,Java要求如下:
equals()相等,hashcode()一定相等;
quals()不等,hashcode()可能相等,也可能不等;
hashcode()不等,一定能推出equals()也不等;
hashcode()相等,equals()可能相等,也可能不等。

Student.class

package test1;


/**
 * @author NSNP736
 * @description StudentBean
 */
public class Student {

    private String Local = "";

    private String Id = "";

    private String number = "";

    private String Code = "";

    private String rtype = "";

    private String Id10digit = "";

    private String nbRtype = "";

    private String fullNm = "";

    private String gender = "";

    private String birthDt = "";

    private String Status = "";

    private String cusId = "";

    public Student() {
        super();
    }

    public Student(String local, String id, String number, String code, String rtype, String id10digit,
            String nbRtype, String fullNm, String gender, String birthDt, String status, String cusId) {
        super();
        Local = local;
        Id = id;
        this.number = number;
        Code = code;
        this.rtype = rtype;
        Id10digit = id10digit;
        this.nbRtype = nbRtype;
        this.fullNm = fullNm;
        this.gender = gender;
        this.birthDt = birthDt;
        Status = status;
        this.cusId = cusId;
    }

    public String getLocal() {
        return Local;
    }

    public void setLocal(String local) {
        Local = local;
    }

    public String getId() {
        return Id;
    }

    public void setId(String id) {
        Id = id;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getCode() {
        return Code;
    }

    public void setCode(String code) {
        Code = code;
    }

    public String getRtype() {
        return rtype;
    }

    public void setRtype(String rtype) {
        this.rtype = rtype;
    }

    public String getId10digit() {
        return Id10digit;
    }

    public void setId10digit(String id10digit) {
        Id10digit = id10digit;
    }

    public String getNbRtype() {
        return nbRtype;
    }

    public void setNbRtype(String nbRtype) {
        this.nbRtype = nbRtype;
    }

    public String getFullNm() {
        return fullNm;
    }

    public void setFullNm(String fullNm) {
        this.fullNm = fullNm;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getBirthDt() {
        return birthDt;
    }

    public void setBirthDt(String birthDt) {
        this.birthDt = birthDt;
    }

    public String getStatus() {
        return Status;
    }

    public void setStatus(String status) {
        Status = status;
    }

    public String getCusId() {
        return cusId;
    }

    public void setCusId(String cusId) {
        this.cusId = cusId;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((Code == null) ? 0 : Code.hashCode());
        result = prime * result + ((Id == null) ? 0 : Id.hashCode());
        result = prime * result + ((Id10digit == null) ? 0 : Id10digit.hashCode());
        result = prime * result + ((Local == null) ? 0 : Local.hashCode());
        result = prime * result + ((Status == null) ? 0 : Status.hashCode());
        result = prime * result + ((birthDt == null) ? 0 : birthDt.hashCode());
        result = prime * result + ((cusId == null) ? 0 : cusId.hashCode());
        result = prime * result + ((fullNm == null) ? 0 : fullNm.hashCode());
        result = prime * result + ((gender == null) ? 0 : gender.hashCode());
        result = prime * result + ((nbRtype == null) ? 0 : nbRtype.hashCode());
        result = prime * result + ((number == null) ? 0 : number.hashCode());
        result = prime * result + ((rtype == null) ? 0 : rtype.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (Code == null) {
            if (other.Code != null)
                return false;
        } else if (!Code.equals(other.Code))
            return false;
        if (Id == null) {
            if (other.Id != null)
                return false;
        } else if (!Id.equals(other.Id))
            return false;
        if (Id10digit == null) {
            if (other.Id10digit != null)
                return false;
        } else if (!Id10digit.equals(other.Id10digit))
            return false;
        if (Local == null) {
            if (other.Local != null)
                return false;
        } else if (!Local.equals(other.Local))
            return false;
        if (Status == null) {
            if (other.Status != null)
                return false;
        } else if (!Status.equals(other.Status))
            return false;
        if (birthDt == null) {
            if (other.birthDt != null)
                return false;
        } else if (!birthDt.equals(other.birthDt))
            return false;
        if (cusId == null) {
            if (other.cusId != null)
                return false;
        } else if (!cusId.equals(other.cusId))
            return false;
        if (fullNm == null) {
            if (other.fullNm != null)
                return false;
        } else if (!fullNm.equals(other.fullNm))
            return false;
        if (gender == null) {
            if (other.gender != null)
                return false;
        } else if (!gender.equals(other.gender))
            return false;
        if (nbRtype == null) {
            if (other.nbRtype != null)
                return false;
        } else if (!nbRtype.equals(other.nbRtype))
            return false;
        if (number == null) {
            if (other.number != null)
                return false;
        } else if (!number.equals(other.number))
            return false;
        if (rtype == null) {
            if (other.rtype != null)
                return false;
        } else if (!rtype.equals(other.rtype))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Student [Local=" + Local + ", Id=" + Id + ", number=" + number + ", Code=" + Code + ", rtype=" + rtype
                + ", Id10digit=" + Id10digit + ", nbRtype=" + nbRtype + ", fullNm=" + fullNm + ", gender=" + gender
                + ", birthDt=" + birthDt + ", Status=" + Status + ", cusId=" + cusId + "]";
    }





}

去重方法:

package test1;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.junit.Assert;


/**
 * @author zhangdi
 * @description Remove duplicates from Lists
 */
public class TestListMethod {
    private final static Logger log = Logger.getLogger(TestListMethod.class);

    @SuppressWarnings("unused")
    public static void main(String[] args) {

        List<Student> orgList = generateListContatinsDuplicates();//why cant be write as a universally method by param to generate wanted Object?
        List<Student> removeDuplicateBeanOfList = removeDuplicateBeanOfList(orgList);// 无序
        List<Student> removeDuplicateBeanOfList2 = removeDuplicateBeanOfList2(orgList);//有序
        List<Student> removeDuplicateBeanOfList3 = removeDuplicateBeanOfList3(orgList);//有序

        List<String> generateListContatinsDuplicates = generateListContatinsDuplicates("1",5000);
        List<String> removeDupliStringList = removeDupliStringList(generateListContatinsDuplicates);
        List<String> removeDupliStringList8 = removeDupliStringListJAVA8(generateListContatinsDuplicates);

        List<Student> generateListContatinsDuplicates2 = generateListContatinsDuplicates(new Student(),5000);
        List<Student> removeDuplicateBeanOfList4 = removeDuplicateBeanOfList(generateListContatinsDuplicates2);//无序
        List<Student> removeDuplicateBeanOfList5 = removeDuplicateBeanOfList2(generateListContatinsDuplicates2);//有序
        List<Student> removeDuplicateBeanOfList6 = removeDuplicateBeanOfList3(generateListContatinsDuplicates2);//有序
    }


    /**
     * @return
     * @description  generate List may contains Duplicates 
     */
    public static List<Student> generateListContatinsDuplicates(){
        long startTime = System.currentTimeMillis();
        List<Student> list = new ArrayList<Student>();
        for (int i = 0; i < 10; i++) {
            // local,id,number,code,rtype,Id10digit,nbRtype,fullNm,gender,birthDt,Status,cusId
            list.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M", "19950212","02", "C01"));
            if (new Random().nextBoolean()) {
                list.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M","19950212", "02", "C01"));
            }
        }
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("generateListContatinsDuplicates time:"+time);
        return list;

    }

    /**
     * @param <T>
     * @return
     * @description generate Duplicates
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> generateListContatinsDuplicates(T str,int count){
        long startTime = System.currentTimeMillis();
        List<T> list = new ArrayList<T>();
        if(str!=null && str instanceof Student){
            List<Student> studentList = new ArrayList<Student>();
            for (int i = 0; i < count; i++) {
                // local,id,number,code,rtype,Id10digit,nbRtype,fullNm,gender,birthDt,Status,cusId
                studentList.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M", "19950212",
                        "02", "C01"));
                if (new Random().nextBoolean()) {
                    studentList.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M",
                            "19950212", "02", "C01"));
                }
            }
            list =  (List<T>) studentList;
        }

        if(str!=null && str instanceof String){
            List<String> strList = new ArrayList<String>();
            for (int i = 0; i < count; i++) {
                strList.add("String"+String.valueOf(i));
                if (new Random().nextBoolean()) {
                    strList.add("String"+String.valueOf(i));
                }
            }
            list =  (List<T>) strList;
        }
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("generateListContatinsDuplicates(T) time:"+time);
        return list;

    }

    /**
     * @param stringList
     * @return
     * @description remove repeated String
     */
    public static List<String> removeDupliStringList(List<String> stringList) {
        long startTime = System.currentTimeMillis();
        Set<String> set = new LinkedHashSet<>();
        set.addAll(stringList);

        stringList.clear();

        stringList.addAll(set);

        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDupliStringList(List<String> stringList) time:"+time);
        return stringList;
    }

    /**
     * @param stringList
     * @return
     * @description remove repeated String use java8 API
     */
    public static List<String> removeDupliStringListJAVA8(List<String> stringList) {
        long startTime = System.currentTimeMillis();
        @SuppressWarnings("unused")
        List<String> unique = stringList.stream().distinct().collect(Collectors.toList());
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDupliStringListJAVA8(List<String> stringList) time:"+time);
        return stringList;
    }

    /**
     * @param list
     * @return
     * @description remove repeated javabean
     */
    public static List<Student> removeDuplicateBeanOfList(List<Student> list) {
        long startTime = System.currentTimeMillis();
        // 重复数据
        List<Student> list2 = new ArrayList<>();
        /*
        for (int i = 0; i < 10; i++) {
            // local,id
            // ,number,code,rtype,Id10digit,nbRtype,fullNm,gender,birthDt,Status,cusId
            list.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M", "19950212",
                    "02", "C01"));
            if (new Random().nextBoolean()) {
                list.add(new Student(String.valueOf(i), "71", "C999", "001", "P", "", "02", "zhangsanfeng", "M",
                        "19950212", "02", "C01"));
            }
        }*/
        // hashset
        HashSet<Student> set = new HashSet<>();
        for (Student pol : list) {
            boolean add = set.add(pol);
            if (!add) {
                list2.add(pol);
            }
        }
        // 比较
        Assert.assertEquals(list.size(), list2.size() + set.size());
        System.out.println(
                "list.size():" + list.size() + " " + "list2.size():" + list2.size() + " " + "set.size():" + set.size());
        // return Arrays.asList(set.toArray());//this clause not return a
        // List<Student> but a List<Object>
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDuplicateBeanOfList(List<Student> list) time:"+time);
        return new ArrayList<Student>(set);
    }

    /**
     * @param list
     * @return
     * @description https://stackoverflow.com/questions/5741038/remove-duplicates-from-arraylists
    * You may need to override "equals()" so that these elements are considered equals 
     */
    public static List<Student> removeDuplicateBeanOfList2(List<Student> list) {
        long startTime = System.currentTimeMillis();
        //remove duplicates if any
        Set<Student> setItems = new LinkedHashSet<Student>(list);
        list.clear();
        list.addAll(setItems);

        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug(" removeDuplicateBeanOfList2(List<Student> list)  time:"+time);
        return list;
    }

    /**
     * @param list
     * @return
     * @description  if one property of List's javabean repeat is the standard to remove DuplicateBean ,may need below method
     */
    public static List<Student> removeDuplicateBeanOfList3(List<Student> list) {
        long startTime = System.currentTimeMillis();
        List<Student> result = new ArrayList<Student>();
        Set<String> titles = new HashSet<String>();

        for( Student item : list ) {
            if( titles.add( item.toString())) {
                result.add( item );
            }
        }
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDuplicateBeanOfList3(List<Student> list) time:"+time);
        return result;
    }

    /**
     * @param list
     * @return
     * @description truely "remove" DuplicateBean   not rely on overriding equals() and hashcode()
     */
    @SuppressWarnings("unchecked")
    public static List<Student> removeDuplicateBeanOfList4(List<Student> list) {
        long startTime = System.currentTimeMillis();
        Set<String> subtitles = new HashSet<String>();
        Iterator<Student> it = null;
        for (it = list.iterator(); it.hasNext(); ) {
            if (!subtitles.add(it.next().toString())) {
                it.remove();
            }
        }
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDuplicateBeanOfList4(List<Student> list) time:"+time);
        return (List<Student>) it;
    }

    /**
     * @param list
     * @return
     * @description use java8API to remove Duplicates
     */
    public static List<Student> removeDuplicateBeanOfListJAVA8(List<Student> list) {
        long startTime = System.currentTimeMillis();
        List<Student> deduped;
        deduped =  list.stream()
                     .distinct()
                     .collect(Collectors.toCollection(ArrayList::new));
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        log.debug("removeDuplicateBeanOfListJAVA8(List<Student> list)  time:"+time);
        return deduped;
    }

    /**
     * @param list
     * @return
     * @description use java8API to remove Duplicates
     */
    public static List<Student> removeDuplicateBeanOfListJAVA8_2(List<Student> list) {
        long startTime = System.currentTimeMillis();
        List<Student> personList = new ArrayList<>();
            // 去重
         list.stream().forEach(
                    p -> {
                        if (!personList.contains(p)) {
                            personList.add(p);
                        }
                    }
            );
            System.out.println(personList);
            long endTime = System.currentTimeMillis();
            long time = endTime-startTime;
            log.debug("removeDuplicateBeanOfListJAVA8(List<Student> list)  time:"+time);
        return personList;
    }
}

log4j.properties:

# \u4E5F\u5C31\u662F\u8BF4\u53EA\u663E\u793A\u6BD4\u5927\u4E8E\u7B49\u4E8E\u5F53\u524D\u7EA7\u522B\u7684\u4FE1\u606F

log4j.rootLogger=debug,appender1  

#log4j.rootLogger=info,appender1  

#log4j.rootLogger=error,appender1    

# \u8F93\u51FA\u5230\u63A7\u5236\u53F0   

log4j.appender.appender1=org.apache.log4j.ConsoleAppender  

# \u6837\u5F0F\u4E3A TTCCLayout  

log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout

参考:https://stackoverflow.com/questions/5741038/remove-duplicates-from-arraylists;
https://blog.csdn.net/jiaobuchong/article/details/54412094

posted @ 2018-04-13 16:21  XueXueLai  阅读(197)  评论(0编辑  收藏  举报