1、模型对象类 User

@Data
@AllArgsConstructor
class User{
    private String name;
    private Integer age;
    private Integer salary;
}

2、测试数据

private static List<User> 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();
    }

    /**
     * 找出年龄小于21的(传统方法)
     */
    private static void m1(){
        List<User> 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();
    }
    /**
     * 找出工资大于4000的(传统方法)
     */
    private static void m2(){
        List<User> 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();
    }

	/**
     * stream流式(多种写法)
     * or
     * and
     */
    private static void m3(){
        // stream
        Predicate<User> predicate1 = user -> user.getAge()<21;
        Predicate<User> predicate2 = user -> user.getSalary()>3000;
        List<User> 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<User> 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<User> users1 = new ArrayList<>();
    /**
     * 现在员工情况
     */
    private static List<User> 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);
    }

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

        List<User> 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);
    }

    /**
     * 名称差集 users2 - users1 -> 小刘
     */
    private static void m5(){
        Predicate<User> p1 =
                user -> users1.stream()
                        //.allMatch(user1 -> !(user.getName()).equalsIgnoreCase(user1.getName()));
        				.noneMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List<User> 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);
    }

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

        List<User> 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);
    }

	/**
     * 名称交集 users2 与 users1 -> 小张、小李
     */
    private static void m7(){
        Predicate<User> p1 =
                user -> users1.stream()
                        .anyMatch(user1 -> (user.getName()).equalsIgnoreCase(user1.getName()));

        List<User> 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);
    }

	/**
     * 并集 users1 与 users2(不是按名称合并;两年前小张 与 现在小张不同)
     * ------------------------
     * 两种方式(本方法采有方式一)
     * -------- 1、 -------------
     * users1 + users2,再去重
     * -------- 2 -------------
     * users1 - users2,得到差集,存入users1中
     * users1(差集结果) + users2,不用去重
     */
    private static void m8(){
        // 通过并行流,得到新集合
        List<User> newUsers1 = users1.parallelStream().collect(Collectors.toList());
        List<User> newUsers2 = users2.parallelStream().collect(Collectors.toList());

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

        // newUsers1去重,结果存入resUsers
        List<User> 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)]
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐