stream().filter()的用法

本文详细介绍Java Stream API中的filter方法使用技巧,通过实例演示如何在List集合中查询特定数据,包括查询符合条件的所有用户及首个用户。

stream().filter()的用法

平时我们会经常看到stream().filter()的方式去查询数据

  • stream.filter一般适用于list集合,主要作用就是模拟sql查询,从集合中查询想要的数据。filter里面的参数user是指集合里面的每一项

我们来一个简单的示例就能看懂他的用法了

public class StreamTest{
    public static void main(String[] args){
        List<User> list = new ArrayList<>();
        //定义三个用户对象
        User user1 = new User();
        user1.setUsername("huxiansen");
        user1.setPassword("123456");
        User user2 = new User();
        user2.setUsername("huxianseng");
        user2.setPassword("123456");
        User user3 = new User();
        user3.setUsername("huxiansen");
        user3.setPassword("12345");
        //添加用户到集合中
        list.add(user1);
        list.add(user2);
        list.add(user3);//在集合中查询用户名为huxiansen的集合
        List<User> userList = list.stream().filter(user -> "huxiansen".equals(user.getUsername())).collect(Collectors.toList());
        //在集合中查询出第一个用户密码为123456的用户
        Optional<User> user = list.stream().filter(userTemp -> "123456".equals(userTemp.getPassword())).findFirst();
​
        System.out.println(userList);
        System.out.println(user);
    }
}```

<think> 我们正在讨论Java Stream API中的filter方法。根据引用[1]、[3]、[4]、[5]中关于filter用法,我们可以总结如下: filterStream的一个中间操作,用于根据条件过滤元素。它接收一个Predicate(一个返回boolean的函数式接口)作为参数,只有满足条件的元素才会被保留在流中。 基本语法: ```java stream.filter(element -> condition) ``` 其中,`element`是流中的每个元素,`condition`是一个布尔表达式,用于判断元素是否应该被保留。 示例1:过滤整数列表中大于5的数(引用[1]) ```java List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List<Integer> filtered = numbers.stream() .filter(n -> n > 5) .collect(Collectors.toList()); // 结果: [6, 7, 8, 9, 10] ``` 示例2:过滤集合中姓名为“gu”的数据(引用[3]) ```java List<QueryUserRspBo> list = ...; // 假设有一些数据 List<QueryUserRspBo> collect = list.stream() .filter(queryUserRspBo -> "gu".equals(queryUserRspBo.getUserName())) .collect(Collectors.toList()); ``` 注意:在比较字符串时,为了避免空指针,建议使用"常量".equals(变量)的方式。 示例3:结合map操作(引用[5]) ```java // 获取合同实体列表中所有的合同ID(先过滤非空,再提取ID) List<String> contractIds = contractEntityList.stream() .filter(contract -> contract.getContractId() != null) // 过滤掉contractId为null的 .map(ContractEntity::getContractId) .collect(Collectors.toList()); ``` 示例4:多重条件过滤(引用[4]) ```java // 过滤出年龄大于18岁且性别为女性的用户 List<User> adultFemales = userList.stream() .filter(user -> user.getAge() > 18 && user.getGender().equals("female")) .collect(Collectors.toList()); ``` 注意事项: 1. filter操作不会改变原有流中的元素,它只是根据条件筛选元素。 2. filter操作是惰性的,只有在终端操作(如collect)执行时才会实际进行过滤。 3. 可以连续使用多个filter,例如: ```java List<User> filteredUsers = userList.stream() .filter(user -> user.getAge() > 18) .filter(user -> user.getSalary() > 5000) .collect(Collectors.toList()); // 等价于 List<User> filteredUsers = userList.stream() .filter(user -> user.getAge() > 18 && user.getSalary() > 5000) .collect(Collectors.toList()); ``` 性能考虑: - 在流操作中,多个连续的filter操作可能比一个包含复杂条件的filter效率稍低(因为每个filter都会遍历一次),但实际差异通常很小,可读性更重要。 其他常见用法: - 配合Optional使用(如findFirst()返回Optional): ```java Optional<User> user = userList.stream() .filter(u -> "admin".equals(u.getRole())) .findFirst(); ``` - 与并行流结合使用(对于大数据集): ```java List<User> filtered = userList.parallelStream() .filter(u -> u.getAge() > 18) .collect(Collectors.toList()); ``` 总结:filterJava Stream API中用于数据筛选的核心方法,通过传递一个条件(Predicate)来过滤出符合条件的元素。它经常与map、collect等方法结合使用,实现数据的处理与收集。 §§相关问题§§ 1. Java Streamfilter和map方法有什么区别? 2. 如何在Java Stream中进行多条件过滤? 3. filter操作在并行流中如何工作? 4. 如何用filter方法处理可能为空的集合? 5. Java Streamfilter和findAny/findFirst如何配合使用? </think> ### Java 中 `.stream().filter()` 使用方法详解 `.stream().filter()` 是 Java 8 Stream API 的核心方法之一,用于**根据条件过滤集合元素**,其基本语法为: ```java 集合.stream() .filter(元素 -> 布尔表达式) .终端操作; ``` #### 一、基础用法 1. **简单条件过滤**(引用[3]): ```java // 过滤年龄大于18的用户 List<User> adults = userList.stream() .filter(user -> user.getAge() > 18) .collect(Collectors.toList()); ``` 2. **多条件过滤**: ```java // 过滤年龄>18且VIP状态为true的用户 List<User> vipAdults = userList.stream() .filter(user -> user.getAge() > 18 && user.isVip()) .collect(Collectors.toList()); ``` 3. **空值安全过滤**: ```java // 安全过滤姓名非空且以"张"开头 List<User> zhangUsers = userList.stream() .filter(user -> user.getName() != null && user.getName().startsWith("张")) .collect(Collectors.toList()); ``` #### 二、组合用法 1. **配合`map()`提取属性**(引用[5]): ```java // 提取所有VIP用户的ID List<String> vipIds = userList.stream() .filter(User::isVip) // 等同于 user -> user.isVip() .map(User::getId) .collect(Collectors.toList()); ``` 2. **配合`anyMatch()`检查存在性**(引用[4]): ```java // 检查是否存在年龄<18的用户 boolean hasMinor = userList.stream() .anyMatch(user -> user.getAge() < 18); ``` 3. **多重过滤链**: ```java // 先过滤北京用户,再过滤VIP List<User> beijingVips = userList.stream() .filter(user -> "北京".equals(user.getCity())) .filter(User::isVip) .collect(Collectors.toList()); ``` #### 三、进阶技巧 1. **使用 Predicate 复用条件**: ```java Predicate<User> adultPredicate = user -> user.getAge() >= 18; // 复用条件 long adultCount = userList.stream().filter(adultPredicate).count(); List<User> adults = userList.stream().filter(adultPredicate).toList(); ``` 2. **过滤后直接操作**: ```java // 过滤后直接修改VIP状态 userList.stream() .filter(user -> user.getPurchase() > 10000) .forEach(user -> user.setVip(true)); ``` 3. **嵌套集合过滤**(引用[2]): ```java List<List<User>> cityGroups = ...; // 从城市分组中过滤出VIP用户并平铺 List<User> allVips = cityGroups.stream() .flatMap(group -> group.stream().filter(User::isVip)) .collect(Collectors.toList()); ``` #### 四、性能注意事项 1. **短路操作优化**: ```java // 找到第一个符合条件的用户后立即停止 Optional<User> firstVip = userList.stream() .filter(User::isVip) .findFirst(); ``` 2. **避免重复计算**: ```java // 错误:多次调用getOrders() .filter(user -> user.getOrders().size() > 5 && user.getOrders().isEmpty()) // 正确:缓存中间结果 .filter(user -> { List<Order> orders = user.getOrders(); return orders.size() > 5 && !orders.isEmpty(); }) ``` #### 五、典型应用场景 ```java // 电商场景:过滤未支付订单 List<Order> unpaidOrders = orderList.stream() .filter(order -> order.getStatus() == OrderStatus.UNPAID) .collect(Collectors.toList()); // 日志分析:过滤错误日志 long errorCount = logList.stream() .filter(log -> log.getLevel() == LogLevel.ERROR) .count(); ``` > **最佳实践**:当过滤条件超过 3 个时,建议改用 `Predicate` 组合条件(如 `.filter(predicate1.and(predicate2))`)提升可读性[^1]。
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值