我在Java 8中有点新,我正在尝试理解以下代码的作用
@Override
public Optional<String> getMostFrequentLastName(final List<User> users) {
return
users.stream()
.collect(Collectors.groupingBy(User::getLastName, Collectors.counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() >= 2)
.reduce((e1, e2) ->
e1.getValue() < e2.getValue() ? e2 :
e1.getValue() > e2.getValue() ? e1 :
new AbstractMap.SimpleEntry<>(null, e1.getValue()))
.map(Map.Entry::getKey);
}
谁能详细解释一下这里发生了什么?
我认为对我来说最令人困惑的是reduce和map部分
reduce
操作在这里非常混乱:
.reduce((e1, e2) -> e1.getValue() < e2.getValue() ? e2 :
e1.getValue() > e2.getValue() ? e1 :
new AbstractMap.SimpleEntry<>(null, e1.getValue()))
我想说的是,这部分令人困惑,归结为格式:
.reduce(
(e1, e2) ->
e1.getValue() < e2.getValue()
? e2
: e1.getValue() > e2.getValue()
? e1
: new AbstractMap.SimpleEntry<>(null, e1.getValue()))
(但只是部分)。
请记住,e*.getValue()
是名称的出现次数。所以,这是在说:
- 如果 name1 出现的次数少于 name2,则 name2 是我们迄今为止找到的最好的名称
- 如果 name2 比 name1 出现次数更多,则 name1 是我们迄今为止找到的最好的名称
- 否则,它们出现次数相同 - 在这种情况下,组成一个新名称
null
,并返回该名称以及出现次数。
返回名称null
有点令人困惑,不知道您的要求 - 看起来这实际上是为了找到出现次数最大的名称,但前提是没有其他名称具有该出现次数。
reduce
将返回一个Optional<Map.Entry<String, Long>>
(如果列表中至少有一个人,则该存在)。后续.map(Map.Entry::getKey)
只是提取名称并丢弃计数。
请注意,在对许多名称发生最大计数的情况下,getKey
返回null
,这意味着该方法总体返回Optional.empty()
。