如何使用列表在地图中分组时过滤年龄

Man*_*ani 6 java grouping filter java-stream java-10

类似我刚才的问题在这里,该用户我有对象是这些

new User("ayush","admin",23)
new User("ashish","guest",19) 
new User("ashish","admin",20) 
new User("garima","guest",29)
new User("garima","super",45)
new User("garima","guest",19)
Run Code Online (Sandbox Code Playgroud)

现在我试图让这些用户知道不同年龄段的名称.但是我需要在一个threshold年龄之上过滤它们.我可以使用这个趋势

Map<String, List<Integer>> userNameAndAgeTrend = users.stream().collect(Collectors.groupingBy(user-> user.getName(), Collectors.mapping(u-> u.getAge(), toList())));
Run Code Online (Sandbox Code Playgroud)

这给了我{ashish=[19, 20], garima=[29, 45, 19], ayush=[23]}.但是在我使用这种分组的情况下,我无法使用阈值正确过滤列表,例如21年.有人可以帮忙吗?

另外,使用.filter(user -> user.getAge() > 21)没有为ashish提供映射,这也是我想要存储的.我可以在我的机器上安装Java10并尝试建议的解决方案.

Nam*_*man 8

Stream.filter

你可以使用filteras

Map<String, List<Integer>> userNameAndAgeTrend = users.stream()
        .filter(a -> a.getAge() > 21) // only above 21
        .collect(Collectors.groupingBy(User::getName, Collectors.mapping(User::getAge, Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)

正如您在评论中所证实的那样,这将为您提供输出

{garima=[29, 45], ayush=[23]}
Run Code Online (Sandbox Code Playgroud)

Collectors.filtering

如果你正在寻找所有的名字,你也可以使用Collectors.filtering,因为,其中明确召唤出一个类似的行为(格式化我的):

使用filtering如上所示的收集器将导致从该部门到空集的映射.

如果filter()改为完成了流操作,那么根本就没有该部门的映射.

它的用法应该类似于:

Map<String, List<Integer>> userNameAndAgeTrend = users.stream()
        .collect(Collectors.groupingBy(User::getName, Collectors.mapping(User::getAge, 
                        Collectors.filtering(age -> age > 21, Collectors.toList()))));
Run Code Online (Sandbox Code Playgroud)

现在的输出就是

{ashish=[], garima=[29, 45], ayush=[23]}
Run Code Online (Sandbox Code Playgroud)


Ous*_* D. 5

如果你想filter 分组之前:

users.stream()
     .filter(u -> u.getAge() > 21) //<--- apply the filter operation
     ...
Run Code Online (Sandbox Code Playgroud)

filter 是一个中间操作,它使人们能够"保持满足所提供的谓词的元素",并排除其他不支持的元素.

因此,在filter操作之后,您将拥有一个仅包含传递提供的谓词的元素的新流.在这种情况下,只有年龄超过21岁的用户.


如果你想filter 分组之后(不要filter在流中混淆,这有点不同)

filteringJDK9 的收集器:

users.stream()
     .collect(groupingBy(User::getName, 
            filtering(u -> u.getAge() > 21, 
                   mapping(User::getAge, toList()))));
Run Code Online (Sandbox Code Playgroud)

看,接受的答案在这里的JDK8实现.

使用filter上面的流,首先过滤值,然后将其分组.换句话说,在过滤后我们对它们"没有痕迹".

但是,随着filtering收集器的到来JDK9我们可以保持一丝.