3
public class ArraysDemo {

    public static void main(String[] args) {

          int[] a = {0, 2, 4, 6, 8};
          int[] b = {10, 12, 14, 16, 18};
          Arrays.setAll(a, i -> b[i]+1);
          System.out.println(Arrays.toString(a));
    }  
}

出力:[11, 13, 15, 17, 19]

使用した関数のソースは次のsetAll()とおりです。

public static void setAll(int[] array, IntUnaryOperator generator) {
        Objects.requireNonNull(generator);
        for (int i = 0; i < array.length; i++)
            array[i] = generator.applyAsInt(i);
}

IntUnaryOperatorは機能的なインターフェースであり、これはそのソースの一部です:

public interface IntUnaryOperator {
    int applyAsInt(int operand);
    // rest methods are omitted
}

間違っている場合は訂正してください。ただし、Java でのラムダ式についての私の理解では、ラムダ式をパラメータとしてメソッドに渡すと、インターフェイスsetAll()を実装する匿名クラスのオブジェクトが作成され、呼び出されます。そして、ラムダ式は本質的にメソッドの実装であるため、次のように変換されると思います。IntUnaryOperatorgeneratorapplyAsInt()

int applyAsInt(int operand){
    return b[operand]+1;
}

operand引数として渡されたときにアクセスできることは理にかなっていますがarray[i] = generator.applyAsInt(i);、どのように操作できるかわかりませんb-パラメーターとして渡されないので、どのように参照できるのでしょうか? 私は何が欠けていますか?

4

3 に答える 3

2
      Arrays.setAll(a, i -> b[i]+1);

次の効果と同等です。

      Arrays.setAll(a, new IntUnaryOperator() {

              private int[] b$ = b;

              @Override
              public int applyAsInt(int i);
                  return b$[i]+1;
              }
          });

これは、b元の変数と同じ名前と値を持つ変数であり、b保持されます。このコピーは、元の変数 (または新しい変数) の寿命が他の変数よりも限られている可能性があるため必要です。たとえば、ローカル変数であること。

2 つの変数が存在することを隠すには、それらを割り当てないようにする必要があります (「実質的に最終的な」)。これにより、「同じ」変数に対して異なる値が生じる可能性があります。

于 2016-08-29T12:30:32.280 に答える