当前位置: 首页 > 知识库问答 >
问题:

使用Java8 streams API和lambdas操作映射

轩辕经国
2023-03-14
Map<Integer, Integer> allHighScoresPerLevel=highScores.get(levelId);
Set<Map.Entry<Integer, Integer>> sortedHighScores=allHighScoresPerLevel.entrySet()
               .stream().limit(Configuration.MAX_HIGHSCORES_DISPLAYED)
               .map((e)->e).sorted((o1,o2)->(o1.getValue().compareTo(o2.getValue())))
               .collect(Collectors.toCollection(TreeSet::new));
java.util.concurrent.ConcurrentHashMap$MapEntry cannot be cast to java.lang.Comparable

1)做这件事的正确方法是什么?我做错了什么?

2)流是线程安全的吗?我正在多线程环境中工作,所以我是否应该使用返回TRAAD安全集合的收集器?

共有1个答案

程毅
2023-03-14

您把事情弄得过于复杂了:除非对象具有可比性(Map.Entrys不具有可比性),否则TreeSet需要一个比较器,并且排序将由TreeSet完成。

这样(使用静态导入):

Set<Entry<Integer, Integer>> sortedHighScores =  allHighScoresPerLevel.entrySet().stream()
            .limit(Configuration.MAX_HIGHSCORES_DISPLAYED)
            .collect(toCollection(() -> new TreeSet<> (Entry.comparingByValue())));

您没有提供足够的信息来知道代码是否是线程安全的-但是如果原始映射是线程安全的,那么您就可以了。

 类似资料:
  • 我不熟悉Java8,不知道如何使用流及其排序方法。如果我有下面的映射,那么如何使用Java8按值对该映射进行排序,从而只获取前10个条目。 我知道在Java 8之前,我们可以按以下链接排序:https://stackoverflow.com/a/109389/4315608

  • 首先,我有下面的发票清单。每个列表对象都有一个零件号、一个描述、数量和一个价格。 我将其映射到数量上,并将其排序到数量上,得到以下结果: 但是我如何在上进行映射,以便在我的结果中显示在所显示的数量前面?我不能这样做:

  • 我目前正在处理Java 8中使用Lambdas进行按位操作的循环转换问题。 给定一组复杂的条目,循环需要遍历所有条目并对它们调用给定的方法(方法返回布尔值)。之后,返回结果。 谢谢!

  • flatMap 遍历所有的元素,为每一个创建一个集合,最后把所有的集合放在一个集合中。 assertEquals(listOf(1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7), list.flatMap { listOf(it, it + 1) }) groupBy 返回一个根据给定函数分组后的map。 assertEquals(mapOf("odd" to listOf(

  • 我目前正在阅读一本Java8Lambdas的书(相当受欢迎),我对其中一个高级问题的答案中的一些语法感到困惑。 问题提出如下问题: 只使用reduce和lambda表达式编写函数'map'的实现。您可以返回而不是。 到目前为止,Java8 lambdas已经非常简单了,我觉得我似乎理解了书中的所有理论,但也许我误解了什么?我想知道我在这里错过了什么?

  • 我的理解是lambda的表达式被用来替换抽象实现的boiler-plater代码。因此,如果我必须创建一个接受可运行接口(函数式)的新线程,我不必创建一个新的匿名类,然后提供void run()并在其中编写逻辑,而是可以简单地使用lambda并将其指向一个方法,前提是方法签名与run相同,即不接受任何内容,也不返回任何内容。 但是我不能理解下面的实现 在上面的例子中,printStudent使用了