如何在Java Stream Filter中使用Map?双数组交集角色名提取报错解决
Java Stream 解决两个数组交集的角色名称提取问题
你遇到的这个错误完全在情理之中——你试图把一个int类型的角色ID,直接和Stream<Integer>类型的对象做==比较,这俩根本不是一个类型,编译器肯定会报错。我来一步步帮你解决这个问题,同时把map在Stream里的用法讲明白。
第一步:先提取权限数组中的所有RoleId(这里用到map)
首先,我们应该把permissions数组里所有的roleId提取出来,存到一个集合里(推荐用HashSet,因为判断元素是否存在的效率极高)。这里的map操作就是用来做类型转换的:它把Stream里的每个Permission对象,转换成对应的roleId属性值。
代码示例:
// 先把权限中的所有roleId收集到Set中,方便后续快速判断 Set<Integer> permissionRoleIds = Arrays.stream(permissions) .map(Permission::getRoleId) // 把Permission对象映射为它的roleId .collect(Collectors.toSet());
第二步:筛选交集并提取角色名称
接下来,我们遍历roles数组,筛选出那些roleId存在于上面集合中的角色,然后再提取它们的roleName,最后收集成列表。
代码示例:
// 注意:这里不需要先new ArrayList再赋值,直接用Stream的结果即可(如果要用final修饰,就直接赋值) List<String> roleNames = Arrays.stream(roles) .filter(role -> permissionRoleIds.contains(role.getRoleId())) .map(Role::getRoleName) // 把符合条件的Role对象映射为它的roleName .collect(Collectors.toList());
关于“在Filter中使用Map”的说明
其实map和filter是Stream的两个独立操作:
map的作用是转换元素的类型(比如把对象转成它的某个属性)filter的作用是筛选符合条件的元素
你不能直接在filter的判断逻辑里嵌套map来做比较,但可以用anyMatch来实现类似的逻辑(不过这种方式效率较低,不推荐大数据量场景):
// 不推荐:每判断一个role就要遍历一遍permissions数组,时间复杂度O(n*m) List<String> roleNames = Arrays.stream(roles) .filter(role -> Arrays.stream(permissions) .map(Permission::getRoleId) .anyMatch(id -> id == role.getRoleId())) .map(Role::getRoleName) .collect(Collectors.toList());
这里的map还是用来转换Permission到roleId,然后用anyMatch判断是否存在匹配的ID。但这种写法效率远不如先把ID收集到集合里的方式,所以尽量用第一种方法。
另外,你原来代码里的final List<String> roleNames = new ArrayList<>();然后又roleNames = ...是错误的——final修饰的变量不能被重新赋值,要么去掉final,要么直接把Stream的结果赋值给roleNames即可。
内容的提问来源于stack exchange,提问作者Milan Panic
相关产品推荐
相关产品推荐

