我在初始化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>();
}
一切都很好。
为什么第一个代码不起作用?这是我的错吗?
谢谢
答案 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],因为你确实在修改数组,而不是第一种方法。