Java程序中的数组奇怪的行为

时间:2011-03-07 13:44:53

标签: java

我遇到了这个Java程序,它以意想不到的方式运行。以下程序计算int数组中元素对之间的差异。

import java.util.*;

public class SetTest
{
       public static void main(String[] args)
       {
            int vals[] = {786,678,567,456,
                          345,234,123,012};

            Set<Integer> diffs = new HashSet<Integer>();

            for(int i=0; i < vals.length ; i++)
                for(int j = i; j < vals.length; j++)
                       diffs.add(vals[i] - vals[j]);

            System.out.print(diffs.size());
       }
}

如果我们分析它似乎设置大小应该是8,这是数组的大小。但是,如果你运行这个程序,它打印14.发生什么事了?任何的想法?

提前谢谢你。

答案:出现这种奇怪的行为是因为如果我们将数组改为12则数组中的012变为八进制,然后按预期打印8。

课程:永远不要用零填充整数文字。

6 个答案:

答案 0 :(得分:11)

你注意到012(八进制)是10(十进制)吗?

答案 1 :(得分:3)

  

如果我们分析它似乎设定大小应该   是8,这是数组的大小。   但如果你运行这个程序就会打印出来   14.发生了什么事?有什么想法吗?

追踪信息

1   : 786 - 786 = 0 (new one 1 )
2   : 786 - 678 = 108   (new one 2 )
3   : 786 - 567 = 219   (new one 3 )
4   : 786 - 456 = 330   (new one 4 )
5   : 786 - 345 = 441   (new one 5 )
6   : 786 - 234 = 552   (new one 6 )
7   : 786 - 123 = 663   (new one 7 )
8   : 786 - 10 = 776    (new one 8 )
9   : 678 - 678 = 0 (already contained)
10  : 678 - 567 = 111   (new one 9 )
11  : 678 - 456 = 222   (new one 10 )
12  : 678 - 345 = 333   (new one 11 )
13  : 678 - 234 = 444   (new one 12 )
14  : 678 - 123 = 555   (new one 13 )
15  : 678 - 10 = 668    (new one 14 )
16  : 567 - 567 = 0 (already contained)
17  : 567 - 456 = 111   (already contained)
18  : 567 - 345 = 222   (already contained)
19  : 567 - 234 = 333   (already contained)
20  : 567 - 123 = 444   (already contained)
21  : 567 - 10 = 557    (new one 15 )
22  : 456 - 456 = 0 (already contained)
23  : 456 - 345 = 111   (already contained)
24  : 456 - 234 = 222   (already contained)
25  : 456 - 123 = 333   (already contained)
26  : 456 - 10 = 446    (new one 16 )
27  : 345 - 345 = 0 (already contained)
28  : 345 - 234 = 111   (already contained)
29  : 345 - 123 = 222   (already contained)
30  : 345 - 10 = 335    (new one 17 )
31  : 234 - 234 = 0 (already contained)
32  : 234 - 123 = 111   (already contained)
33  : 234 - 10 = 224    (new one 18 )
34  : 123 - 123 = 0 (already contained)
35  : 123 - 10 = 113    (new one 19 )
36  : 10 - 10 = 0   (already contained)

此外,如果您无法分析程序的行为,调试器是一件好事;)

答案 2 :(得分:3)

由于您运行两个嵌套循环,因此多次调用add()方法。由于集合不能包含重复对象,因此集合中的值的数量将是唯一值的数量。如果集合尚未包含元素,则add()函数返回true,如果集合已经具有元素,则返回false。

更改行

diffs.add(vals[i] - vals[j]);

System.out.println((diffs.add(vals[i] - vals[j])));

看看我的意思。

答案 3 :(得分:-1)

对于一组8个元素,有36个(8 + 7 + ... + 1)个不同的对(如果忽略对中元素的顺序)。因此diffs可能包含最多 36个元素。但显然,一些差异会多次出现,例如456-345 = 111和345-234 = 111.由于一个集合最多只能包含一个值,因此只剩下14个不同的差异。

答案 4 :(得分:-1)

您的HashSet仅存储非重复值。如果需要重复项,则必须使用不同的集类型。差异的大小应为36,重复;当我按原样运行代码时,我的大小为19(19个唯一不同的值)。

答案 5 :(得分:-1)

它实际打印出19 ......

你有36个计算,其中17个具有相同的结果。 HashSet只保留唯一值,这就是为什么我们没有36的大小但是大小为19 ...