自定义对象集合List之间取差集

前言

在工作中少不了使用集合类来处理数据,List是最常用的一种集合了。这些集合类使用都非常的方便,但是使用集合存放一些自定义的对象时,就需要注意使用这些方法了。
这里主要讲一下List之间的差集该怎么取。

正文

原生Api

如果集合中存放的是基本数据类型或字符串类型,List提供了交集、差集、并集的这些方法。使用如下:

需求 调用方法 说明
交集 listA.retainAll(listB) 调用方法后ListA变为两个集合的交集,ListB不变
差集 listA.removeAll(listB) 调用方法后ListA变为两个集合的差集,ListB不变
并集 1.listA.removeAll(listB) 2.listA.addAll(listB) 去重,先取差集再并集。ListA变为两个集合的并集,ListB不变

使用场景:List泛型指定为基本数据类型或字符串。

List<String> list = new ArrayList<>();

自定义对象List差集

假设有Student类和Student对象集合listA、listB。通过对象的id判断为相等,对两个集合求差集

public class Student {
    private String id;
    private String name;
    //get set方法...
}

思路:遍历listA,判断当前Student对象,如果存在于listB中就从listA中取出,最后返回ListA对ListB的差集。
1.遍历listA:
遍历的方法有for循环、增强for循环和迭代器,使用迭代器遍历listA并删除元素避免出错。
2.判断当前对象是否存在于listB中,使用HashSet来协助操作。首先遍历listB,将对象id放入HashSet中,然后使用迭代器遍历listA,判断当前对象id是否存在于HashSet中即是否存在ListB。
方法代码:

    /**
     * 差集:删除左边集合中在右边集合存在的元素并返回
     * @param left
     * @param right
     * @return
     */
    private static List<Student> removeAll(List<Student> left, List<Student> right){
        if (left == null){
            return null;
        }
        if (right == null){
            return left;
        }
        //使用LinkedList方便插入和删除
        List<Student> res = new LinkedList<>(left);
        Set<String> set = new HashSet<>();
        //将Student id存放到set
        for(Student item : right){
            set.add(item.getId());
        }
        //迭代器遍历listA
        Iterator<Student> iter = res.iterator();
        while(iter.hasNext()){
            Student item = iter.next();
            //如果set中包含id则remove
            if(set.contains(item.getId())){
                iter.remove();
            }
        }
        return res;
    }

调用实现 listA = removeAll(listA, listB);

交集和并集的操作类似:
交集:如果set中包含id则添加到交集listC,listC.add(student)。
并集:如果set中包含id则continue,否则添加到listA,Iterator不提供add方法,使用ListIterator.add(student)见下面介绍。
注意的一点是: remove是使用迭代器的remove方法,而不是使用list的remove方法

ListIterator

如果你想在遍历的时候进行修改或添加操作而不是删除,请使用ListIterator
ListIterator的使用和Iterator几乎一样,不同的是ListIterator提供了更多的方法对list进行操作,包括添加元素add和修改set.

        ListIterator<Student> iter = res.listIterator();
        while(iter.hasNext()){
            Student item = iter.next();
            //1.remove
            if(set.contains(item.getId())){
                iter.remove();
            }
            //2.add
            if(set.contains(item.getId())){
                iter.add(new Student("11","小明"));
            }

            //3.修改 set
            if(set.contains(item.getId())){
                //对应自定义的对象没必要使用set进行修改
                item.setName("小黄");
//                iter.set(item);
                //如果遍历的是List,就可以使用set修改当前遍历String对象的值
//                iter.set("Hello ListIteraroe!");
            }
        }

参考

原生方法:list的交集,差集,并集
自定义对象集合求差集:两个list求差集
ListIterator的更多使用:listIterator,可以边遍历边修改

你可能感兴趣的:(Java)