2012-12-11 73 views
0

我有一个问题,初始化数组HashSet的初始化HashSet的数组中的Java

int N = 100; 
    HashSet<Integer> []array = new HashSet[N]; 
    for (HashSet<Integer> set:array){ 
    set = new HashSet<Integer>(); 
    } 

,但该数组只包含空值。与运行时(也错误时的HashSet []数组= ....)

但:

for(int i = 0; i < N; i++){ 
     array[i] = new HashSet<Integer>(); 
    } 

一切都很好。

为什么第一个代码不工作?这是我的错误吗?

谢谢

+0

你没有错。 – irrelephant

回答

2

你从来没有真正分配初始化的实例在数组中的元素。相反,你用一个变量来遍历数组的元素,该变量被分配给循环中的一个新对象,然后永远不会被使用。在这种情况下,针对...每种语法的增强功​​能都不合适,请改用传统的for循环。

+0

谢谢!我想我明白了,它现在甚至是有意义的:) –

+0

@AL - for ... each循环中的变量是一个本地作用域引用,它与实际存储在数组(实际上不存在,因为数组只包含空值)。为它赋值只在for ... each循环中有意义,但实际上并不改变数组。 – Perception

+0

是的,我在开始时回复了第一篇文章。非常感谢您(您和MouseEvent)的详细说明。答案非常好,专注于我。 :-) –

0

一种enhanced for loop,阵列中不使用实际的实例(和为好,集合),而是将它们复制在循环控制变量。

这不应该是非空值的问题,因为它们指向相同的对象。问题出现了,如果值为空,并且将值重新分配给控制变量,则不会改变实际值。因此,在这种情况下,请始终使用常规for循环。

原始类型的数组也是如此,因为对它们进行处理并更改复制的变量不会影响原始变量。

+0

谢谢!就像我上面所说的一样。 –

0

一个第一个:

int N = 100; 
    HashSet<Integer> []array = new HashSet[N]; 
    for (HashSet<Integer> set:array){ 
    set = new HashSet<Integer>(); 
    } 

您没有真正改变阵列的位置,是set临时副本变量。而不是第二种方法中发生的事情。

如果测试:

int N = 100; 
       HashSet<Integer> []array = new HashSet [N]; 
       for (HashSet<Integer> set:array){ 
       set = new HashSet<Integer>(); 
       set.add(1); 
       } 
       System.out.println(array[0]); 

它仍然会打印空。

在另一方面在此:

int N = 100; 
       HashSet<Integer> []array = new HashSet [N]; 
       for(int i = 0; i < N; i++){ 
        array[i] = new HashSet<Integer>(); 
        array[i].add(1); 
       } 
       System.out.println(array[0]); 

将打印您[1],因为你确实修改阵列,不会像第一种方法。

1

两个 '关于' 是在Java中不同,看java代码&字节码.. 实施例:

public class T{ 
     public static void main(String[] args){ 
      String[] data = new String[10]; 
      System.out.print(""); 
      for(String str:data){ 
       str="1"; 
      } 
      System.out.print(""); 
      for(int i=0;i<data.length;i++){ 
       data[i]="1"; 
      } 
     } 
    } 

$>javac -classpath . T.java 
$>javap -c T 


Compiled from "T.java" 
public class T extends java.lang.Object{ 
public T(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: bipush 10 
    2: anewarray #2; //class java/lang/String 
    5: astore_1 
    6: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    9: ldC#4; //String 
    11: invokevirtual #5; //Method java/io/PrintStream.print:(Ljava/lang/String;)V 
    14: aload_1 
    15: astore_2 
    16: aload_2 
    17: arraylength 
    18: istore_3 
    19: iconst_0 
    20: istore 4 
    22: iload 4 
    24: iload_3 
    25: if_icmpge 44 
    28: aload_2 
    29: iload 4 
    31: aaload 
    32: astore 5 
    34: ldC#6; //String 1 
    36: astore 5 
    38: iinc 4, 1 
    41: goto 22 
    44: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    47: ldC#4; //String 
    49: invokevirtual #5; //Method java/io/PrintStream.print:(Ljava/lang/String;)V 
    52: iconst_0 
    53: istore_2 
    54: iload_2 
    55: aload_1 
    56: arraylength 
    57: if_icmpge 71 
    60: aload_1 
    61: iload_2 
    62: ldC#6; //String 1 
    64: aastore 
    65: iinc 2, 1 
    68: goto 54 
    71: return 

} 

从线25--44和线57--71: aload:检索对象从一个局部变量引用并将它推到操作数堆栈上。 aaload:获取从物体的阵列的对象的引用,并把它压入堆栈。

astore:将对象或引用存储到局部变量。aastore:将参考类型的值存储到数组中。

所以,先不能存储数组,没有使用初始化数组。