Java 8 使用修改后的值重新映射

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25466664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:27:41  来源:igfitidea点击:

Java 8 re-map with modified value

javacollectionslambdajava-8java-stream

提问by Garret Wilson

I'm about to get a grasp on the new Java 8 stream and lambda options, but there are still a few subtleties that I haven't yet wrapped my mind around.

我即将掌握新的 Java 8 流和 lambda 选项,但仍有一些微妙之处我尚未解决。

Let's say that I have a map where the keys are the names of people. The value for each name is a map of ages and Personinstances. Further assume that there does not exist more than one person with the same name and age.

假设我有一张地图,其中的键是人名。每个名称的值是年龄和Person实例的映射。进一步假设同名同龄的人不超过一个。

Map<String, NavigableMap<Long, Person>> names2PeopleAges = new HashMap<String, NavigableMap<Long, Person>>();

After populating that map (elsewhere), I want to produce another map of the oldest person for each name. I want to wind up with a Map<String, Person>in which the keys are identical to those in the first map, but the value for each entry is the value of the value map for which the key of the value map has the highest number.

在填充该地图(在其他地方)之后,我想为每个名字生成另一个最年长的人的地图。我想最终得到一个Map<String, Person>,其中的键与第一个映射中的键相同,但是每个条目的值是值映射的键具有最高编号的值映射的值。

Taking advantage of the fact that a NavigableMapsorts its keys, I can do this:

利用 aNavigableMap对其键进行排序的事实,我可以这样做:

Map<String, Person> oldestPeopleByName = new HashMap<String, Person>();
names2PeopleAges.forEach((name, peopleAges) -> {
  oldestPeopleByName.put(name, peopleAges.lastEntry().getValue());
});

Question:Can I replace the last bit of code above with a single Java 8 stream/collect/map/flatten/etc. operation to produce the same result? In pseudo-code, my first inclination would be:

问题:我可以用单个 Java 8 stream/collect/map/flatten/etc 替换上面的最后一段代码吗?操作产生相同的结果?在伪代码中,我的第一个倾向是:

Map<String, Person> oldestPeopleByName = names2PeopleAges.forEachEntry().mapValue(value->value.lastEntry().getValue());

This question is meant to be straightforward without any tricks or oddities---just a simple question of how I can fully leverage Java 8!

这个问题很简单,没有任何技巧或奇怪之处——只是一个关于如何充分利用 Java 8 的简单问题!

Bonus:Let's say that the NavigableMap<Long, Person>above is instead merely a Map<Long, Person>. Could you extend the first answer so that it collects the person with the highest age value, now that NavigableMap.lastEntry()is not available?

奖励:假设NavigableMap<Long, Person>上面的只是一个Map<Long, Person>. 您能否扩展第一个答案,以便它收集年龄值最高的人,现在NavigableMap.lastEntry()不可用?

采纳答案by Eran

You can create a Stream of the entries and collect it to a Map :

您可以创建条目的 Stream 并将其收集到 Map :

Map<String, Person> oldestPeopleByName = 
    names2PeopleAges.entrySet()
                    .stream()
                    .collect (Collectors.toMap(e->e.getKey(),
                                               e->e.getValue().lastEntry().getValue())
                             );

Now, without lastEntry:

现在,没有lastEntry

Map<String, Person> oldestPeopleByName = 
    names2PeopleAges.entrySet()
                    .stream()
                    .collect (Collectors.toMap(e->e.getKey(),
                                               e->e.getValue().get(e.getValue().keySet().stream().max(Long::compareTo)))
                             );

Here, instead of relying on lastEntry, we search for the maxkey in each of the internal Maps, and get the corresponding Person of the max key.

在这里,我们不依赖于lastEntry,而是max在每个内部Maps 中查找key ,得到 max key 对应的 Person。

I might have some silly typos, since I haven't actually tested it, by in principle it should work.

我可能有一些愚蠢的错别字,因为我还没有真正测试过它,原则上它应该可以工作。