gpt4 book ai didi

java - 随机 ArrayIndexOutOfBoundsException,使用流按值对 Map 元素进行排序

转载 作者:搜寻专家 更新时间:2023-11-01 01:51:11 25 4
gpt4 key购买 nike

在过去的几天里,我开始“玩”一些 Java 8 特性,例如流(我研究了一些文档和几个示例)。

在我的应用程序中,我有一个 Map,我需要获取具有最高值的三个元素(浮点部分)。

我尝试对我的代码进行不同的修改(其中一些解决方案还:Sort a Map<Key, Value> by values (Java)),例如:

Map<Long, Float> great = createMapWith20Elements();
Map<Long, Float> small = great.entrySet().stream()
.sorted(Map.Entry.<Long, Float>comparingByValue().reversed())
.limit(3)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

但结果总是一样的:有时代码运行良好,有时它给了我一个

java.lang.ArrayIndexOutOfBoundsException: 19

在极少数情况下,索引超出范围是 18。

这种“随机”行为(18、19 或正确的阐述)让我想到了“并行线程”问题。

我确定 great map 总是有 20 个元素...如果我打印它们,我会收到:

2,-0.5
3,0.0
4,0.0
5,0.0
6,0.0
7,-0.33333334
8,0.0
9,0.0
10,0.0
11,0.0
12,0.5
13,0.0
14,0.0
15,-0.5
18,0.0
19,0.0
21,0.0
22,0.0
23,0.0
24,0.0

我知道有 17 个对象有可能成为前 3 个...但这对我的算法来说不是问题。

你能以某种方式帮助我吗?

谢谢

编辑:

createMapWith20Elements() 方法有一个虚拟名称,以便更好地解释我的情况:我确信它返回 20 个元素,因为它进行了 DB 读取...但它应该返回任何匹配的记录。

顺便说一下,它以

结尾
// myIds is an ArrayList<Long>
myIds.parallelStream().forEach(e -> trust.put(e, 0f));
return trust;

替换为 myIds.stream() 它似乎工作正常......我无法弄清楚如何使用 parallelStream 写入对象( Collection 而不是 Stream),并返回对象本身 (Collection),在调用函数中它会导致这种问题。

最佳答案

我认为问题出在 createMapWith20Elements() 方法上。

您同时在映射(可能是 HashMap 或 TreeMap)中插入元素,并且 HashMap 和 TreeMap 都不同步。因此并发插入(调用 put 方法)破坏了 map 结构(你得到了一个损坏的 map )。

正如你所说:

// myIds is an ArrayList<Long>
myIds.parallelStream().forEach(e -> trust.put(e, 0f));
return trust;

有时会产生错误。但是

// myIds is an ArrayList<Long>
myIds.stream().forEach(e -> trust.put(e, 0f));
return trust;

不会产生错误。

如果要并发插入,则必须使用同步包装器。所以你的代码应该是:

// myIds is an ArrayList<Long>
Map<Long, Float> syncTrust = Collections.synchronizedSortedMap(trust);
myIds.parallelStream().forEach(e -> syncTrust.put(e, 0f));
return trust;

关于java - 随机 ArrayIndexOutOfBoundsException,使用流按值对 Map 元素进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31014333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com