原文:https://blog.csdn.net/freelander_j/article/details/52211010

在java中,要将一个集合中重复的对象除去,如果这个集合中的数据类型是基本数据类型,可以直接将list集合转换成set,就会自动去除重复的元素,大家都知道set集合的特点就是没有重复的,这个就相对比较简单,这里不在详细说,我们下面说的list集合中的数据类型是一个对象类型的。

当list集合中存储的类型是对象类型的时候,我们就不能简单的只把list集合转换成set集合就行了,这时我们需要在对象的实体类中去重写equals()方法和hashCode()方法,我们以一个list集合为例,在该例中,我们将People实体类中姓名和电话号码作为判断该对象重复的标识,在People的实体类中我们重写这两个方法如下:

  1. public class People {
  2. private String name;
  3. private int id;
  4. private String phoneNumber;
  5. private int age;
  6. private String introduce;
  7. public People(String name, int id, String phoneNumber, int age,
  8. String introduce) {
  9. super();
  10. this.name = name;
  11. this.id = id;
  12. this.phoneNumber = phoneNumber;
  13. this.age = age;
  14. this.introduce = introduce;
  15. }
  16. // ....... 这里省略getter和setter方法
  17. @Override
  18. public boolean equals(Object arg0) {
  19. // TODO Auto-generated method stub
  20. People p = (People) arg0;
  21. return name.equals(p.name) && phoneNumber.equals(p.phoneNumber);
  22. }
  23. @Override
  24. public int hashCode() {
  25. // TODO Auto-generated method stub
  26. String str = name + phoneNumber;
  27. return str.hashCode();
  28. }
  29. }

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

  1. public class Test {
  2. public static void main(String[] args) {
  3. List<People> listPeople = new ArrayList<People>();
  4. listPeople.add(new People("张三", 1, "13355556666", 23, "新员工"));
  5. listPeople.add(new People("张三", 2, "15522223333", 23, "老员工"));
  6. listPeople.add(new People("李四", 3, "13355556666", 23, "实习生"));
  7. listPeople.add(new People("提莫", 4, "13311112222", 23, "经理"));
  8. listPeople.add(new People("张三", 5, "13355556666", 23, "会计"));
  9. listPeople.add(new People("德玛", 6, "3344", 23, "开发"));
  10. listPeople.add(new People("卡特", 7, "13355556666", 23, "测试"));
  11. listPeople.add(new People("提莫", 8, "13355556666", 23, "美工"));
  12. listPeople.add(new People("提莫", 9, "13311112222", 23, "实施"));
  13. listPeople.add(new People("卡兹克", 10, "13356786666", 23, "售前"));
  14. listPeople.add(new People("亚索", 11, "13355556666", 23, "销售"));
  15. Set<People> setData = new HashSet<People>();
  16. setData.addAll(listPeople);
  17. System.out.println("list- size----" + listPeople.size());
  18. System.out.println("list-----" + listPeople.toString());
  19. System.out.println("set- size----" + setData.size());
  20. System.out.println("set-----" + setData.toString());
  21. for(People pp : setData) {
  22. System.out.println("p--" + pp.toString());
  23. }
  24. }
  25. }

运行这段代码之后,我们就会发现,在原来的list集合中姓名和电话号码都相同的对象就被会认为是重复的元素而删除掉,很明显运行结果已经达到我们的目的。

这里需要说一下equals()方法和hashCode()方法,一般情况下我们重写equals()方法的时候都要去重写hashCode()方法,这是为什么呢?大家不妨可以这样去试一试上面那个例子,在实体类中将重写的hashCode()方法注释掉,再去运行该程序,这时就会发现运行结果并不是我们刚刚得到的结果,在set集合中,并没有将我们认为是重复的元素删除掉,下面我们通过这两个方法的源码去了解一下:

String类中的equals()方法的源码如下

  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. }

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

String类中hashCode()方法的源码如下

  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. for (int i = 0; i < len; i++) {
  8. h = 31*h + val[off++];
  9. }
  10. hash = h;
  11. }
  12. return h;
  13. }

以上是String类中重写的hashCode()方法,在Object类中的hashCode()方法是返回对象的32位JVM内存地址,也就是说如果我们不去重写该方法,将会返回该对象的32位JVM内存地址,以上我们测试的例子中,当注释掉重写的hashCode()方法时,这时默认返回对象的32JVM中的地址,两个不同的对象地址显然是不同的,我们在比较时,虽然通过重写的equals()方法比较出来name和phoneNumber值是相同的,但是默认的hashCode()方法返回的值他们并不是同一个对象,所以我们通常要将hashCode()方法与equals()方法一起重写,以维护hashCode方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

曾在网上一篇博客中看到过这样的解释,用白话说,通过hashCode判断对象是否放在同一个桶里,然后再通过equals方法去判断这个桶里的对象是不是相同的,这个比喻也挺形象的。

关于hashCode方法的作用大家可以看看这篇博客,讲的很清楚:http://blog.csdn.net/fenglibing/article/details/8905007

转载于:https://www.cnblogs.com/tc310/p/9306520.html

List集合去除重复对象及equals()、hashCode()方法的作用相关推荐

  1. java list 重复对象_list集合去除重复对象的实现

    对象重复是指对象里面的变量的值都相等,并不定是地址.list集合存储的类型是基础类型还比较好办,直接把list集合转换成set集合就会自动去除. 当set集合存储的是对象类型时,需要在对象的实体类里面 ...

  2. list集合去除重复对象

       对象重复是指对象里面的变量的值都相等,并不定是地址.list集合存储的类型是基础类型还比较好办,直接把list集合转换成set集合就会自动去除. 当set集合存储的是对象类型时,需要在对象的实体 ...

  3. android 去重 比较两个list_android 去重 比较两个list_Android 去除list集合中重复项的几种方法...

    因为用到list,要去除重复数据,尝试了几种方法.记录于此... 测试数据: List li1 = new List { "", "", "" ...

  4. android 去重 比较两个list_Android 去除list集合中重复项的几种方法

    因为用到list,要去除重复数据,尝试了几种方法.记录于此... 测试数据: List li1 = new List { "", "", "" ...

  5. JAVA中list.contains()方法,要重写equals(),hashcode()方法

    今天动力节点java培训机构小编为大家介绍"JAVA中list.contains()方法,要重写equals(),hashcode()方法",希望能够帮助正在学习java的零基础学 ...

  6. 去除html重复的元素 js,js数组中去除重复值的几种方法

    在日常开发中,我们可能会遇到将一个数组中里面的重复值去除,那么,我就将我自己所学习到的几种方法分享出来 去除数组重复值方法: 1,利用indexOf()方法去除 思路:创建一个新数组,然后循环要去重的 ...

  7. 使用set集合去除重复元素

    如何使用set集合去重 我们都知道,set集合是无序的,这样也导致set集合里面的元素是不能重复的,因为这一个特性,所以我们经常用set集合进行去重操作,我们下面以一个简单的例子说明set集合是如何进 ...

  8. 深入理解C# Unity List集合去除重复项 Distinct

    C#集合中如何去除重复项? 于是你百度了一波,找到以下解决方案. 第一种:两次循环遍历 List<int> repeatList= new List<int>() { 1, 2 ...

  9. 去除list集合中重复项的几种方法

    因为用到list,要去除重复数据,尝试了几种方法.记录于此... 测试数据: List<string> li1 = new List<string> { "8&quo ...

  10. java去除重复对象_Java19-2 集合类去除重复对象

    List独有方法: import java.util.ArrayList; import java.util.List; public class ListTest2 { public static ...

最新文章

  1. 多款eclipse黑色坏境任你选择,只要导入配置
  2. 沟通:用故事产生共鸣
  3. 青年节寄语和新课程免费上架
  4. RegularExpressionValidator 常用
  5. r语言c5.0决策树算法参数,决策树算法CART、C5.0的R语言实现——(三)
  6. Pandas——筛选数据(loc、iloc)
  7. 研究生马上要毕业了,可是完全写不出论文,该退学吗?
  8. 初次见面——C语言的整体把握【小白福音】
  9. 注销linux用户的方法,Linux下注销登录用户的方法
  10. group by 与 order by的用法
  11. Python:百分制转五分制
  12. 【数据产品案例】阿里XSigma智能客服调度平台
  13. OllyDBG 寄存器窗口
  14. [唐诗]寻西山隐者不遇-丘为
  15. Alibaba fastjson 序列化与反序列化
  16. 用iOS模拟器安装App
  17. Unity解析gif动态图
  18. 关于win10系统cmd命令失效
  19. 《虚拟化与云计算技术》实训
  20. php反调试,简单对抗某个驱动的反调试

热门文章

  1. java模拟安卓get请求,Java模拟HTTP Get Post请求实现论坛自动回帖功能
  2. excel如何将英文星期转为中文星期_用Excel制作偶像日历的体验,你一定不能错过...
  3. lbs的核心技术都有哪些?_直击现场 | 腾讯云“揭秘智慧出行核心技术与创新实践”活动完美落幕!...
  4. kubernetes视频教程笔记 (29)-安全-认证Authentication
  5. 微信小程序云开发教程-一个js文件如何包含多个云函数
  6. linux赋权限2770,Linux权限:SUID,SGID以及粘滞位
  7. 远程计算机统考试题,2015年电大远程网络教育计算机应用基础统考模拟试题集...
  8. 转字符串_【转】什么是字符串?字符串是用来做什么的?
  9. 十九、Math和Random类
  10. L3_08——图中所有边都是相等的常数