利用Set在两个集合中做找不同

工作需求,需要做文件对账功能。
简单点讲,就是两个集合,找出这两个集合中不同的元素。
算法我就不自己写了。可以用Set解决这个问题。
HashSet不能添加重复的元素,当调用add(Object)方法时候, 首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素; 如果已存在则调用Object对象的equals方法判断是否返回true, 如果为true则说明元素已经存在,如为false则插入元素。

所以我们要先重写对象的hashCode()方法和equals()方法。
代码如下:

@Override
public int hashCode(){
  return this.getAmount();
}

@Override
public boolean equals(Object o){
  if(o instanceof ReconciliationBean){
    ReconciliationBean bean=(ReconciliationBean)o;
      boolean isOrder=bean.getOrderNo().equals(this.getOrderNo());
      boolean isStatus=bean.getStatus().equals(this.getStatus());
    if(isOrder&&isStatus){
      return true;
    }else{
      return false;
    }
  }else{
    return false;
  }
}

重写了hashCode()方法和equals()方法后,就可以用Set来找不同了。
代码如下:

  public Set<ReconciliationBean> reconciliation(List<ReconciliationBean> ourDocuments, List<ReconciliationBean> otherFile) {
    Set<ReconciliationBean> or= new HashSet<ReconciliationBean>();
    Set<ReconciliationBean> and=new HashSet<ReconciliationBean>();
    if(ourDocuments!=null&&otherFile!=null){
        or.addAll(ourDocuments);
        or.addAll(otherFile);
        and.addAll(ourDocuments);
        and.retainAll(otherFile);
        or.removeAll(and);
    }
    return or;
}

为此我准备了两个一样的文件,然后从其中一个文件找出三条数据,分别修改amount,status,orderNo状态。

运行之后

2FDF5621-5391-4611-BA88-91E5FCBD9F9A.png

问题出现了。
少了一条数据。我修改了克隆文件中的三条数据,应该最后返回的集合有六条数据才对。而且集合and做了求交集的动作,应该是211条数据而不是212条数据才对。

辛苦调试之后,发现在调用retainAll方法的时候,并没有调用hashCode()方法。而且对于Object.hashCode()有如下约定

  • 在程序的一次执行中,无论何时在同一个java对象上重复调用hashcode(),都必须一致地返回同一个整数值,并不像Object.equals()那样提供Object是否被修改了的信息,但这个整数值不必在同一个应用程序的多次运行之间保持一致.
  • 如果两个Object通过equals()判断是相等的,那么,在这两个Object上调用hashcode()必返回相同的值.
  • 如果两个Object通过equals()判断是不相等的,那么,并不要求这两个Object.hashcode()返回不同的整数值.

(⊙v⊙)嗯!解决如下:

@Override
public boolean equals(Object o){
  if(o instanceof ReconciliationBean){
    ReconciliationBean bean=(ReconciliationBean)o;
      boolean isOrder=bean.getOrderNo().equals(this.getOrderNo());
      boolean isStatus=bean.getStatus().equals(this.getStatus());
      boolean isAmount=bean.getAmount().equals(this.getAmount());
    if(isOrder&&isStatus&&isAmount){
      return true;
    }else{
      return false;
    }
  }else{
    return false;
  }
}

运行结果如下:

3F164EE8-BB1C-4E3B-A13E-56BAE7906E07.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,981评论 18 399
  • 上一篇文章介绍了Set集合的通用知识。Set集合中包含了三个比较重要的实现类:HashSet、TreeSet和En...
    Ruheng阅读 15,822评论 3 57
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 5,403评论 0 3
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 11,942评论 0 62
  • 继周六鹞子峪之后,今天又去明长城了。 已累劈 最近天气都好好,日出也很美 回顾活动的简易招聘贴写的是上升500,下...
    爱吃肉的慕凝阅读 2,312评论 0 0