美文网首页程序员Java学习笔记
利用Set在两个集合中做找不同

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

作者: cat昵称居然被占用了 | 来源:发表于2017-02-21 19:31 被阅读378次

    工作需求,需要做文件对账功能。
    简单点讲,就是两个集合,找出这两个集合中不同的元素。
    算法我就不自己写了。可以用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

    相关文章

      网友评论

        本文标题:利用Set在两个集合中做找不同

        本文链接:https://www.haomeiwen.com/subject/xhiuwttx.html