gpt4 book ai didi

java - Immutable.listCopyfOf 抛出 ArrayIndexOutOfBoundsException

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:48:26 25 4
gpt4 key购买 nike

我正在使用 google gauva 版本 11.0.1 并有这段代码:

ImmutableList.copyOf(items);

其中 items 是一个 ConcurrentLinkedQueue。我偶尔会看到这个错误:

java.lang.ArrayIndexOutOfBoundsException: 10
at java.util.AbstractCollection.toArray(AbstractCollection.java:126)
at com.google.common.collect.ImmutableList.copyFromCollection(ImmutableList.java:278)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:247)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:217)

鉴于问题完全出在 guava 库中,有人知道为什么吗?

根据以下正确答案更新

感谢 wolfcaSTLe 的帮助,我设法在我的应用程序之外独立地重现了这个问题。

final int itemsToPut = 30000;

final ConcurrentLinkedQueue<Integer> items = new ConcurrentLinkedQueue<Integer>();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < itemsToPut; i++) {
items.add(i);
}
}
}, "putter-thread").start();
final Iterable<String> transformed = Collections2.transform(items, new Function<Integer, String>() {
public String apply(Integer integer) {
return "foo-" + integer;
}
});
ImmutableList.copyOf(transformed);

每次运行都会产生以下结果:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 21480
at java.util.AbstractCollection.toArray(AbstractCollection.java:126)
at com.google.common.collect.ImmutableList.copyFromCollection(ImmutableList.java:278)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:247)
at com.google.common.collect.ImmutableList.copyOf(ImmutableList.java:217)

为了解决我的申请,我找到了很多选择。

远离 Collections2

通过从 Collections2.transform 切换到 Iterables.transform,问题就消失了。

远离 Java 1.5

虽然这在我的情况下是不可能的,但我在 Java 1.6 和 Java 1.7 上尝试过,问题就消失了。我怀疑这是由于 AbstractCollection.toArray() 从 1.5 开始的实现发生了变化:

1.5

public Object[] toArray() {
Object[] result = new Object[size()];
Iterator<E> e = iterator();
for (int i=0; e.hasNext(); i++)
result[i] = e.next();
return result;
}

1.6

public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}

首先复制 ConcurrentLinkedQueue

对非线程安全集合执行转换显然远非理想。如果出于某种原因我必须继续使用 Collections2.transform,我可以通过先获取项目集合的副本来解决问题。

最佳答案

您的集合的 toArray() 方法似乎有问题。您说您正在使用 ConcurrentLinkedQueue,但您的堆栈跟踪显示 AbstractCollection.toArray。这似乎有问题,因为 java.util.ConcurrentLinkedQueue 有自己的 toArray 实现。

您真正使用的是什么集合?我怀疑是集合而不是 ImmutableList

关于java - Immutable.listCopyfOf 抛出 ArrayIndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18385310/

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