Java中List集合去重(二)

关于List中对象去重,如果List中存储的数据类型是基本数据类型,可直接将list集合转换成set集合,或采用其他方法,上篇有陈述。本篇说下list集合中的数据类型是一个对象类型的情况,需要在对象的实体类中去重写equals()方法和hashCode()方法

在该例中,我们将User实体类中用户编码和姓名作为判断该对象重复的标识,在User实体类中我们重写这两个方法如下:


public class User {
private int id;
private String userCd;
private String userNm;
private String phone;
private String memo;


public User(int id, String userCd, String userNm, String phone, String memo) {
super();
this.id = id;
this.userCd = userCd;
this.userNm = userNm;
this.phone = phone;
this.memo = memo;
}


public int getId() {
return id;
}


public void setId(int id) {
this.id = id;
}


public String getUserCd() {
return userCd;
}


public void setUserCd(String userCd) {
this.userCd = userCd;
}


public String getUserNm() {
return userNm;
}


public void setUserNm(String userNm) {
this.userNm = userNm;
}


public String getPhone() {
return phone;
}


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


public String getMemo() {
return memo;
}


public void setMemo(String memo) {
this.memo = memo;
}


@Override
public boolean equals(Object arg0) {
User u = (User) arg0;
return userCd.equals(u.userCd) && userNm.equals(u.userNm);
}


@Override
public int hashCode() {
String str = userCd + userNm;
return str.hashCode();
}
}


        以上实体类中,我们在equals()方法中取出该对象的userCd和userNm这两个属性值去判断比较,然后在重写的hashCode()方法中返回这两个属性值得hashCode值。

package xuGroup.xuArtifact;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class Test2 {


public static void main(String[] args) {
// TODO Auto-generated method stub
List<User> userList = new ArrayList<User>();
userList.add(new User(1, "001", "张三", "13355556666", "前端"));
userList.add(new User(2, "002", "张三", "15522223333", "前端"));
userList.add(new User(3, "003", "李四", "13355556666", "后端"));
userList.add(new User(4, "004", "王五", "13311112222", "总监"));
userList.add(new User(5, "002", "张三", "13355556666", "设计"));


Set<User> setData = new HashSet<User>();
setData.addAll(userList);
System.out.println("list- size----" + userList.size());
System.out.println("list-----" + userList.toString());


System.out.println("set- size----" + setData.size());
System.out.println("set-----" + setData.toString());


for (User pp : setData) {
System.out.println("p--" + pp.toString());
}
}
}

      

    一般情况下我们重写equals()方法的时候都要去重写hashCode()方法,


        String类中的equals()方法的源码如下, 通过观察equals()方法的源码我们可以看出,该方法去比较两个对象时,首先先去判断两个对象是否具有相同的地址,如果是同一个对象的引用,则直接放回true;如果地址不一样,则证明不是引用同一个对象,接下来就是挨个去比较两个字符串对象的内容是否一致,完全相等返回true,否则false。

[java]  view plain  copy
  1. public boolean equals(Object anObject) {  
  2.     if (this == anObject) {  
  3.         return true;  
  4.     }  
  5.     if (anObject instanceof String) {  
  6.         String anotherString = (String)anObject;  
  7.         int n = count;  
  8.         if (n == anotherString.count) {  
  9.             char v1[] = value;  
  10.             char v2[] = anotherString.value;  
  11.             int i = offset;  
  12.             int j = anotherString.offset;  
  13.             while (n-- != 0) {  
  14.                 if (v1[i++] != v2[j++])  
  15.                     return false;  
  16.             }  
  17.             return true;  
  18.         }  
  19.     }  
  20.     return false;  
  21. }  
    

        String类中hashCode()方法的源码如下,在Object类中的hashCode()方法是返回对象的32位JVM内存地址,也就是说如果我们不去重写该方法,将会返回该对象的32位JVM内存地址。

[java]  view plain  copy
  1. public int hashCode() {  
  2.     int h = hash;  
  3.     if (h == 0 && count > 0) {  
  4.         int off = offset;  
  5.         char val[] = value;  
  6.         int len = count;  
  7.   
  8.         for (int i = 0; i < len; i++) {  
  9.             h = 31*h + val[off++];  
  10.         }  
  11.         hash = h;  
  12.     }  
  13.     return h;  
  14. }  
        这个测试的例子中,当注释重写的hashCode()方法时,这时默认返回对象的32JVM中的地址,两个不同的对象地址显然是不同的,我们在比较时,虽然通过重写的equals()方法比较出来userCd和userNm值是相同的,但是默认的hashCode()方法返回的值他们并不是同一个对象,所以我们通常要将hashCode()方法与equals()方法一起重写,以维护hashCode方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

        摘抄一句,用白话说,通过hashCode判断对象是否放在同一个桶里,然后再通过equals方法去判断这个桶里的对象是不是相同的,这个比喻是否挺形象,哈哈。


更多可参考:

http://blog.csdn.net/fenglibing/article/details/8905007

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值