如何对Java Developer类的Stream按指定codePost规则过滤去重?
注:题目规则中提到的codeExperience为笔误,实际对应类属性codeLevel,以下实现均按此逻辑处理。
实现思路
- 首先按
codePost对所有Developer分组,过滤规则均基于相同codePost的组内判断 - 对每个分组判断组内的
codeLevel是否唯一:- 若唯一:直接返回整个分组的所有元素,满足同
codePost同codeLevel全部保留的规则 - 若不唯一:过滤仅保留
codeLevel=5的元素,满足同codePost不同codeLevel仅保留5级的规则
- 若唯一:直接返回整个分组的所有元素,满足同
- 最后用
flatMap把所有分组处理后的结果合并为一个新的Stream
代码实现
首先补全Developer类的必要构造、getter方法:
class Developer{ private Long id; private String name; private Integer codePost; private Integer codeLevel; // 全参构造方法 public Developer(Long id, String name, Integer codePost, Integer codeLevel) { this.id = id; this.name = name; this.codePost = codePost; this.codeLevel = codeLevel; } // 必要的属性getter public Integer getCodePost() {return codePost;} public Integer getCodeLevel() {return codeLevel;} @Override public String toString() { return "Developer{" + "id=" + id + ", name='" + name + '\'' + ", codePost=" + codePost + ", codeLevel=" + codeLevel + '}'; } }
流过滤逻辑实现:
import java.util.stream.Collectors; import java.util.stream.Stream; public class DeveloperFilter { public static void main(String[] args) { Developer dev1 = new Developer (1L,"Alan stonly",30,4); Developer dev2 = new Developer (2L,"Peter Zola",20,4); Developer dev3 = new Developer (3L,"Camilia Frim ",30,5); Developer dev4 = new Developer (4L,"Antonio Alcant",40,4); Stream<Developer> developers = Stream.of(dev1, dev2, dev3 , dev4); Stream<Developer> filteredStream = developers // 按codePost分组 .collect(Collectors.groupingBy(Developer::getCodePost)) .values() .stream() // 按规则处理每个分组 .flatMap(group -> { // 判断分组内是否所有codeLevel相同 boolean allSameLevel = group.stream() .map(Developer::getCodeLevel) .distinct() .count() == 1; if (allSameLevel) { return group.stream(); } else { return group.stream().filter(dev -> dev.getCodeLevel() == 5); } }); // 测试输出结果 filteredStream.forEach(System.out::println); } }
输出结果
Developer{id=2, name='Peter Zola', codePost=20, codeLevel=4} Developer{id=3, name='Camilia Frim ', codePost=30, codeLevel=5} Developer{id=4, name='Antonio Alcant', codePost=40, codeLevel=4}
可选性能优化
如果处理的数据量较大,可以将分组内的两次流遍历合并为一次遍历,减少性能损耗:
.flatMap(group -> { Set<Integer> levelSet = new HashSet<>(); boolean hasLevel5 = false; for (Developer dev : group) { levelSet.add(dev.getCodeLevel()); if (dev.getCodeLevel() == 5) { hasLevel5 = true; } } if (levelSet.size() == 1) { return group.stream(); } return hasLevel5 ? group.stream().filter(d -> d.getCodeLevel() == 5) : Stream.empty(); })
内容的提问来源于stack exchange,提问作者bloudr
相关产品推荐
相关产品推荐

