java8两个集合取交集、并集与差集

2021年12月22日 635点热度 0条评论

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

(以上高大上的名词解释内容来自网络,楼主一脸懵B...总之一句话,集合间的去重操作,在java8的流式操作中,变得很优雅,/花鸡)

比如有以下类:

1 Class Person{
2     private int id;
3     private String name;

4     public Person(){}
5     public Person(int id, String name){
6         this.id=id;
7         this.name = name;
8     }  
9 }

然后有以下俩集合:

 1 List<Person> listA = new ArrayList<>();
 2 List<Person> listB = new ArrayList<>();

 3 listA.add(new Person(1,"aa"));
 4 listA.add(new Person(1,"bb"));
 5 listA.add(new Person(1,"cc"));
 6 listA.add(new Person(1,"dd"));
 7 
 8 listB.add(new Person(1,"aa"));
 9 listB.add(new Person(1,"bb"));
10 listB.add(new Person(1,"cc"));

现在希望集合listA与listB之间发生点事,擦出点火花,比如标题上说的求交集(listA ∩ ListB)、求并集(listA ∪ listB)、求差集(listA - listB)。

由于两集合里保存的是对象信息,它们在进行如上操作时,要有比较判断依据,比如,id值和姓名值相同的情况下,认为俩个集合保存的是相同的对象数据。

此时,我们需要先重写Person类的equals方法,如下:

Class Person{
     private int id;
     private String name;

     public Person(){}
     public Person(int id, String name){
         this.id=id;
         this.name = name;
     } 

    @override
    public boolean equals(Object obj){
        if(this ==  obj){
            return true;
        }
        if(obj == null){
            return false;
        }
        if(getClass() != obj.getClass()){
            return false;
        }
        Person other = (Person) obj;
        if(id != other.id){
            return false;
        }
        if(name == null){
            if(other.name != null){
                return false;
            }
        }else if(!name.equals(other.name)){
            return false;
        }
        return true;
    } 
}

最后,优雅地写出集合listA与listB之间发生的那些事吧。

交集(listA ∩ ListB):

List<Person> listC = listA.stream().filter(item -> listB.contains(item)).collect(Collectors.toList());

listC中的元素有:属性name值为 aa, bb, cc 的对象。

并集(listA ∪ listB):

//先合体
listA.addAll(listB);
//再去重
List<Person> listC = listA.stream().distinct().collect(Collectors.toList());

listC中的元素有:属性name值为 aa, bb, cc ,dd的对象。

差集(listA - listB):

List<Person> listC = listA.stream().filter(item -> !listB.contains(item)).collect(Collectors.toList());

listC中的元素有:属性name值为 dd的对象。

harry

这个人很懒,什么都没留下

文章评论