集合的泛型是集合,然后在外集合找重复的子集合

问题:

  • 集合A的泛型是集合B,子集合B泛型是自定义对象,判定新增的集合C在集合A中是否有重复的子集合。

解决方法:

  • 判断是否包含使用retainAll,如果A.retainAll(C),A中有数据,表示有重复数据

两种使用

  1. 如果集合泛型是自定义对象,使用retainAll(),最终调用的方法是自定义对象的equals方法。比较的是属性值是否相同

    public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            // 遍历每个元素【自定义对象】
            for (Node<E> x = first; x != null; x = x.next) {
                // 调用自定义对象的equals方法
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }
    
    // 比较属性值是否相同
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Stu stu = (Stu) o;
        return Objects.equals(name, stu.name) &&
            Objects.equals(age, stu.age) &&
            Objects.equals(createTime, stu.createTime);
    }
    
  2. 如果A集合泛型是子集合,在使用retainAll(),方法判断逻辑是遍历集合A,获取每一个子集合,判断子集合与新增的集合B是否相同。判断逻辑是调用的父类的AbstractList中的equals方法,该方法会判断每一个集合与新增的集合列表长度是否相同,按照顺序一一调用元素的equals方法比较数据是否相同(集合的第一个元素与另外一个集合第一个元素是否相同,集合的第二个元素与另外一个集合第二个元素是否相同……)。

    这里要注意两个集合添加的元素要一一对应。如果拿到的数据不是一一对应,那比较的结果就是false。在判断新增的C中里面的数据是乱序的。如果有一种方法,我们对请求添加的元素进行排好序,对已经存在的所有列表中的元素都进行排序就可以解决。这时候就用到了重写hashcode,可以使用Comparator对元素的hashcode进行排序,因为重写后的hashcode值是通过属性值计算得到的,如果两个对象即使是不同的对象(new出来的),但是属性值是相同的,那么它们的hashcode值也是一样的,这样就满足了我们的业务要求
    

    AbstractList中的equals方法

    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;
    
        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((List<?>) o).listIterator();
        // 比较集合A与集合B中按照次序比较元素是否相同
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        // 长度是否相同
        return !(e1.hasNext() || e2.hasNext());
    }
    

    最终解决方案:

    1. 使用hashcode对每一个子集合进行排序,保证子集合元素按照一定顺序排列
    2. 使用equals方法进行比较数据是否相同
    

    案例一

    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * @Description:
     * @Author party-abu
     * @Date 2021/12/26 20:51
     */
    public class TestSimpleList {
    
        public static void main(String[] args) {
    
            List<Stu> numListInnerOne = new LinkedList<>();
            Stu stu01 = new Stu();
            stu01.setAge(19);
            stu01.setName("张三");
    
            Stu stu03 = new Stu();
            stu03.setAge(33);
            stu03.setName("张三1");
            numListInnerOne.add(stu01);
            numListInnerOne.add(stu03);
    
            System.out.println("=========================");
    
            List<Stu> numListInnerTwo = new LinkedList<>();
            Stu stu02 = new Stu();
            stu02.setAge(19);
            stu02.setName("张三");
    
            Stu stu04 = new Stu();
            stu04.setAge(33);
            stu04.setName("张三1");
            numListInnerTwo.add(stu02);
            numListInnerTwo.add(stu04);
    
            // 取交集
            numListInnerOne.retainAll(numListInnerTwo);
            System.out.println(numListInnerOne.size() > 0 ? "包含" : "不包含");
    
        }
    }
    

    案例二

    import java.util.*;
    
    /**
     * @Description:
     * @Author party-abu
     * @Date 2021/12/26 20:51
     */
    public class TestComplex {
    
        public static void main(String[] args) {
    
            List<List<Stu>> numListOut = new LinkedList<>();
    
            List<Stu> numListInnerOne = new LinkedList<>();
            Stu stu01 = new Stu();
            stu01.setAge(19);
            stu01.setName("张三");
            numListInnerOne.add(stu01);
    
            Stu stu02 = new Stu();
            stu02.setAge(22);
            stu02.setName("小明");
            numListInnerOne.add(stu02);
    
            numListInnerOne.sort(Comparator.comparingInt(Stu::hashCode));
    
            List<Stu> numListInnerTwo = new LinkedList<>();
            Stu stu03 = new Stu();
            stu03.setAge(20);
            stu03.setName("李四");
            numListInnerTwo.add(stu03);
    
            numListOut.add(numListInnerOne);
            numListOut.add(numListInnerTwo);
    
            System.out.println("================================================");
    
            List<Stu> numListInnerRequest = new LinkedList<>();
            Stu stu04 = new Stu();
            stu04.setAge(19);
            stu04.setName("张三");
    
            Stu stu05 = new Stu();
            stu05.setAge(22);
            stu05.setName("小明");
    
            numListInnerRequest.add(stu04);
            numListInnerRequest.add(stu05);
            // 不进行排序,调换上边两个stu04、stu05顺序结果会不一样
            numListInnerRequest.sort(Comparator.comparingInt(Stu::hashCode));
    
            List<List<Stu>> listList = new LinkedList<>();
            listList.add(numListInnerRequest);
    
            // 取交集
            numListOut.retainAll(listList);
            System.out.println(numListOut.size() > 0 ? "包含" : "不包含");
    
        }
    }
    
posted @ 2022-07-04 21:14  永无八哥  阅读(24)  评论(0编辑  收藏  举报