栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中Stream流式实现集合的差集、交集与并集

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中Stream流式实现集合的差集、交集与并集

1、模型对象类 User
@Data
@AllArgsConstructor
class User{
    private String name;
    private Integer age;
    private Integer salary;
}
2、测试数据
private static List users1 = new ArrayList<>();

static {
    users1 = Arrays.asList(
        new User("小张",20,3000),
        new User("小王",21,3500),
        new User("小李",19,5000)
    );
}    
3、传统方式测试 3.1、求年龄小于21的员工
    @Test
    public void test1(){
        m1();
    }

    
    private static void m1(){
        List newUser_1 = new ArrayList<>();
        for (User user : users1) {
            if(user.getAge() < 21){
                newUser_1.add(user);
            }
        }
        System.out.println(newUser_1);
    }
// 结果
[User(name=小张, age=20, salary=3000), User(name=小李, age=19, salary=5000)]
3.2、求工资大于4000的员工
    @Test
    public void test1(){
        m2();
    }
    
    private static void m2(){
        List newUser_2 = new ArrayList<>();
        for (User user : users1) {
            if(user.getSalary() > 4000){
                newUser_2.add(user);
            }
        }
        System.out.println(newUser_2);
    }
// 结果
[User(name=小李, age=19, salary=5000)]
4、Stream流式测试
  • 找出年龄小于21,且工资大于3000的员工
    @Test
    public void test1(){
        m3();
    }

	
    private static void m3(){
        // stream
        Predicate predicate1 = user -> user.getAge()<21;
        Predicate predicate2 = user -> user.getSalary()>3000;
        List userList = users1.stream()
                //.filter(predicate1)
                //.filter(user -> user.getAge()<21)
                //.filter(predicate2)
                //.filter(user -> user.getSalary()>3000)
                .filter(predicate1.and(predicate2))
                //.filter(predicate1.or(predicate2))
                .collect(Collectors.toList());
        System.out.println(userList);
    }
// 结果
[User(name=小李, age=19, salary=5000)]
  • 找出名字是 小李 的员工
    @Test
    public void test1(){
        m9();
    }    

	
    private static void m9(){
        List userList = users1.stream()
                .filter(user -> "小李".equalsIgnoreCase(user.getName()))
                .collect(Collectors.toList());

        System.out.println(userList);
    }
// 结果

[User(name=小李, age=19, salary=5000)]
5、Stream流式升级测试:差、交、并集

以集合中元素中某一属性作为判断标准,如果这一属性相等,就表示该元素相等,忽略其它属性值。

如:两个集合中都有 name = “小张” 的员工,一个集合是两年前,一个是现在的,可以认为这两个 ”小张“ 是同一个人。(差集、交集中这样比较)

自已项目中有类似的使用场景。

5.1、数据模型
	
    private static List users1 = new ArrayList<>();
    
    private static List users2 = new ArrayList<>();

    static {
        // 两年前
        users1 = Arrays.asList(
                new User("小张",20,3000),
                new User("小王",21,3500),
                new User("小李",19,5000)
        );

        // 现在
        users2 = Arrays.asList(
                new User("小张",22,4000),
                new User("小刘",23,4500),
                new User("小李",21,6000)
        );
    }
5.2、(姓名)差集1:离职员工
    @Test
    public void test1(){
        // 名称差集 u1 -u2
        m4();

        // 计算后的原集合不受影响
        System.out.println("n----- user1 -----");
        System.out.println(users1);

        System.out.println("n----- user2 -----");
        System.out.println(users2);
    }

	
    private static void m4(){
        // 断言表达式:如果当前user的name,在users2中不存在,就返回true;allMatch()比较users2中的每一个元素;也可以用noneMatch()
        Predicate p1 =
                user -> users2.stream()
                    //.allMatch(user1 -> !(user.getName()).equalsIgnoreCase(user1.getName()));
        			.noneMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List newUsers1 = users1.stream()
                .filter(p1)
                .collect(Collectors.toList());
        System.out.println("差集 u1 - u2");
        System.out.println(newUsers1);
    }
// 结果

差集 u1 - u2
[User(name=小王, age=21, salary=3500)]

----- user1 -----
[User(name=小张, age=20, salary=3000),
 User(name=小王, age=21, salary=3500), 
 User(name=小李, age=19, salary=5000)]

----- user2 -----
[User(name=小张, age=22, salary=4000),
 User(name=小刘, age=23, salary=4500), 
 User(name=小李, age=21, salary=6000)]
5.3、(姓名)差集2:新员工
	@Test
    public void test1(){
        // 名称差集 u2 -u1
        m5();
        
        // 计算后的原集合不受影响
        System.out.println("n----- user1 -----");
        System.out.println(users1);

        System.out.println("n----- user2 -----");
        System.out.println(users2);
    }

    
    private static void m5(){
        Predicate p1 =
                user -> users1.stream()
                        //.allMatch(user1 -> !(user.getName()).equalsIgnoreCase(user1.getName()));
        				.noneMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List newUsers1 = users2.stream()
                .filter(p1)
                .collect(Collectors.toList());
        System.out.println("差集 u2 - u1");
        System.out.println(newUsers1);
    }
// 结果

差集 u2 - u1
[User(name=小刘, age=23, salary=4500)]

----- user1 -----
[User(name=小张, age=20, salary=3000), 
 User(name=小王, age=21, salary=3500), 
 User(name=小李, age=19, salary=5000)]

----- user2 -----
[User(name=小张, age=22, salary=4000), 
 User(name=小刘, age=23, salary=4500), 
 User(name=小李, age=21, salary=6000)]
5.4、(姓名)交集

交集中,users1 与 users2不分先后顺序,结果一样(姓名相同,但元素是前一个集合中)

  • users1 与 users2

    结果是users1中的部分元素

	@Test
    public void test1(){
        // 名称交集 u1 与 u2
        m6();
        
        // 计算后的原集合不受影响
        System.out.println("n----- user1 -----");
        System.out.println(users1);

        System.out.println("n----- user2 -----");
        System.out.println(users2);
    }

	
    private static void m6(){
        // 断言表达式:当前user中的name名称,在users2集合中,只要有一个名称相等,即为true;anyMatch()只要有一个比对成功就返回    
        Predicate p1 =
                user -> users2.stream()
                        .anyMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List newUsers1 = users1.stream()
                .filter(p1)
                .collect(Collectors.toList());
        System.out.println("交集 u1 与 u2");
        System.out.println(newUsers1);
    }
// 交集:结果是u1中的元素

交集 u1 与 u2
[User(name=小张, age=20, salary=3000), 
 User(name=小李, age=19, salary=5000)]

----- user1 -----
[User(name=小张, age=20, salary=3000), 
 User(name=小王, age=21, salary=3500), 
 User(name=小李, age=19, salary=5000)]

----- user2 -----
[User(name=小张, age=22, salary=4000), 
 User(name=小刘, age=23, salary=4500), 
 User(name=小李, age=21, salary=6000)]
  • users2 与 users1

    结果是users2中的部分元素

	@Test
    public void test1(){
        // 名称交集 u2 与 u1
        m7();
        
        // 计算后的原集合不受影响
        System.out.println("n----- user1 -----");
        System.out.println(users1);

        System.out.println("n----- user2 -----");
        System.out.println(users2);
    }

	
    private static void m7(){
        Predicate p1 =
                user -> users1.stream()
                        .anyMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List newUsers1 = users2.stream()
                .filter(p1)
                .collect(Collectors.toList());
        System.out.println("交集 u2 与 u1");
        System.out.println(newUsers1);
    }
// 结果:结果是u2中的元素

交集 u2 与 u1
[User(name=小张, age=22, salary=4000), 
User(name=小李, age=21, salary=6000)]

----- user1 -----
[User(name=小张, age=20, salary=3000), 
User(name=小王, age=21, salary=3500), 
User(name=小李, age=19, salary=5000)]

----- user2 -----
[User(name=小张, age=22, salary=4000), 
User(name=小刘, age=23, salary=4500), 
User(name=小李, age=21, salary=6000)]
5.5、并集

元素按完全相等来比较,并非按名称;

并集不分前后顺序;

实际项目中暂时没有按名称比较来计算并集

    @Test
    public void test1(){
        // 并集 u1 与 u2
        m8();

        // 计算后的原集合不受影响
        System.out.println("n----- user1 -----");
        System.out.println(users1);

        System.out.println("n----- user2 -----");
        System.out.println(users2);
    }

	
    private static void m8(){
        // 通过并行流,得到新集合
        List newUsers1 = users1.parallelStream().collect(Collectors.toList());
        List newUsers2 = users2.parallelStream().collect(Collectors.toList());

        // 合并;结果存入newUsers1中,可能有重复
        newUsers1.addAll(newUsers2);

        // newUsers1去重,结果存入resUsers
        List resUsers = newUsers1.stream()
                .distinct()
                .collect(Collectors.toList());

        System.out.println("并集 u1 与 u2");
        System.out.println(resUsers);
    }
// 结果

并集 u1 与 u2
[User(name=小张, age=20, salary=3000), 
 User(name=小王, age=21, salary=3500), 
 User(name=小李, age=19, salary=5000), 
 User(name=小张, age=22, salary=4000), 
 User(name=小刘, age=23, salary=4500), 
 User(name=小李, age=21, salary=6000)]

----- user1 -----
[User(name=小张, age=20, salary=3000), 
 User(name=小王, age=21, salary=3500), 
 User(name=小李, age=19, salary=5000)]

----- user2 -----
[User(name=小张, age=22, salary=4000), 
 User(name=小刘, age=23, salary=4500), 
 User(name=小李, age=21, salary=6000)]
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1013220.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号