Java中初始化的HashSet数组

时间:2012-12-11 01:44:58

标签: java collections initialization

我在初始化HashSet数组时遇到问题

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

但是数组只包含null。 (当HashSet [] array = ....)

时也会出错

但在运行时:

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

一切都很好。

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

谢谢

4 个答案:

答案 0 :(得分:2)

您永远不会将初始化实例分配给数组元素。相反,您使用一个变量来迭代数组的元素,该变量被分配给循环中的新对象,然后永远不会被使用。在这种情况下,增强的...每种语法都不合适,而是使用传统的for循环。

答案 1 :(得分:1)

两个'for'在Java中是不同的,看看java代码&amp;字节码.. 例如:

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:将引用类型值存储到数组。

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

答案 2 :(得分:0)

enhanced for loop,不使用数组中的实际实例(以及集合),而是将它们复制到循环控制变量中。

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

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

答案 3 :(得分: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],因为你确实在修改数组,而不是第一种方法。