Java 8方法使用流解释



我在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()

最新更新