0

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

4 に答える 4

3

初期化されたインスタンスを配列の要素に実際に割り当てることはありません。代わりに、ループ内の新しいオブジェクトに割り当てられた変数を使用して配列の要素を反復処理し、使用されることはありません。このような場合、拡張された for...each 構文は適切ではありません。代わりに従来の for ループを使用してください。

于 2012-12-11T01:47:06.507 に答える
1

2つの「for」は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 : 参照型の値ストアを配列に取ります。

そのため、最初に配列を格納できず、配列の初期化を使用していませんでした。

于 2012-12-11T02:28:15.110 に答える
0

は、配列 (およびコレクション) 内の実際のインスタンスを使用するのenhanced for loopではなく、それらをループ制御変数にコピーします。

null 以外の値は同じオブジェクトを指しているため、これは問題になりません。値が null の場合に問題が発生し、制御変数に値を再割り当てしても実際の値は変更されません。したがって、この場合は常に通常のforループを使用してください。

プリミティブ型の配列にも同じことが当てはまります。それらをコピーしてコピーした変数を変更しても、元の変数には影響しないからです。

于 2012-12-11T01:53:23.737 に答える