【发布时间】:2018-09-07 08:30:24
【问题描述】:
我对简单的 for 循环有疑问,不知道问题的原因。
简而言之 - 我没有生成 1, 2, 3, 4, 5... 值,而是收到 4, 4, 4, 4, 8...
情况:
在我的应用程序中,我需要生成一个填充了从 1 到 N 的值的int array[]。它在 99% 的情况下都可以正常工作,但是我很少收到用户的投诉,因为为他们生成的数字不正确,从而破坏了应用程序的逻辑.感谢应用程序版本对有问题的代码进行了特殊记录,我能够查明问题的位置,但我不知道是什么原因造成的。代码如下:
// problematic code
(...)
int[] randomIds = new int[mColumns * mRows];
for (int i = 0; i < randomIds.length; i++) {
randomIds[i] = i + 1;
}
int debugNoValues = 36;
logIntArrayValues(randomIds, debugNoValues);
(...)
// logging method, used to pinpoint the place
// at which wrong values are first seen
private void logIntArrayValues(int[] array, int n){
String s = "";
for(int i=0; i<array.length && i<n; i++){
s+=array[i]+" ";
}
Logger.log(s);
}
由于问题的奇怪性质,我粘贴了实际使用的代码,没有更改任何内容。
变量 mColumns 和 mRows 可以取 3 到 6 之间的值,并且这些值始终相等,因此大小为 9、16、25 或 36。
变量debugNoValues 仅用于测试,可能会限制记录值的数量。在当前状态下,它没有任何限制。
现在最奇怪的部分 - 报告问题的用户收到的值(由Logger.log(s); 记录)如下:
4 4 4 4 8 8 8 8 9
4 4 4 4 8 8 8 8 12 12 12 12 16 16 16 16
4 4 4 4 8 8 8 8 12 12 12 12 16 16 16 16 20 20 20 20 24 24 24 24 25
4 4 4 4 8 8 8 8 12 12 12 12 16 16 16 16 20 20 20 20 24 24 24 24 28 28 28 28 32 32 32 32 36 36 36 36
我无法在我的任何测试设备上重现该问题。报告来自使用 Android 7.x 并具有联发科处理器的设备(至少在我收到有关系统和设备的信息时)。
任何想法可能导致这种行为?我怀疑循环有某种奇怪的优化,但我找不到任何关于它的信息。除此之外我一无所知。
【问题讨论】:
-
你不会在任何时候将
randomIds传递给另一个线程并在那里搞乱它吗? -
尝试在数组中使用 lambda 来设置您的值。 public static
void setAll(T[] array, IntFunction extends T> generator) -
@Koger 好的,我只是想问问。称我为愤世嫉俗者,但根据我在这里的经验,人们倾向于忽略与问题相关的最重要的代码......比如将数据传递到单独线程的代码。
-
@Koger,出于性能原因,请尽量不要在
log方法中直接附加到String。使用StringBuilder.append。并不是说它会自行解决问题。 -
@CharlesSpencer,确实可能是在本地重新实现
Arrays.setAll(int[], IntUnaryOperator)的情况,因为此时数组值应该被视为基于索引的真实函数结果,没有资格进行任何类型的优化行。