9

Integerオブジェクトに10を掛けて、オブジェクトを取り戻すにはどうすればよいIntegerですか?

私はこれを行うための最も良い方法を探しています。

私はおそらくこのようにします:Integerオブジェクトからintを取得し、それを他のintと乗算し、このint値を使用して別のIntegerオブジェクトを作成します。

コードは次のようになります...

integerObj = new Integer(integerObj.intValue() * 10);

しかし、作成者が次のように実行しているコードを見ました。オブジェクトからを取得し、最後に「0」を連結してから、を使用してオブジェクトを取得Stringします。IntegerIntegerInteger.parseInt

コードは次のようなものです。

String s = integerObj + "0";
integerObj = Integer.parseInt(s);

どちらの方法でもメリットはありますか?

そして、一般的に、そしてこの場合、最も効率的/最も近い方法は何でしょうか?

4

6 に答える 6

27

Java 5のオートボクシングを使用すると、次のことが簡単にできます。

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);
于 2008-09-05T14:52:57.907 に答える
7

文字列のアプローチは面白いですが、それを行うにはほぼ間違いなく悪い方法です。

整数のint値を取得し、新しい値を作成するのは非常に高速ですが、parseIntの呼び出しにはかなりのコストがかかります。

全体として、私はあなたの元のアプローチに同意します(他の人が指摘しているように、Java 5で導入されたオートボクシングがあれば、それほど混乱することなく実行できます)。

于 2008-09-05T14:52:19.237 に答える
3

2 番目の方法の問題は、Java で文字列を処理する方法です。

  • "0"コンパイル時に定数 String オブジェクトに変換されます。
  • このコードが呼び出されるたびsに、新しい String オブジェクトとして構築され、そのコードが(古いバージョンの場合は StringBuffer) にjavac変換されます。String s = new StringBuilder().append(integerObj.toString()).append("0").toString()同じを使用してもintegerObj、つまり、

    String s1 = integerObj + "0"; String s2 = integerObj + "0";

    (s1 == s2)だろうfalses1.equals(s2)そうなるだろうtrue

  • Integer.parseIntは不変new Integer()であるため、とにかく内部的に呼び出します。Integer

ところで、オートボクシング/アンボクシングは内部的に最初の方法と同じです。

于 2008-09-05T17:59:01.237 に答える
1

2番目のアプローチには近づかないでください。Java1.5を使用している場合は、オートボクシングが最善の策です。最初の例よりも前の方が最適です。

于 2008-09-05T14:56:08.540 に答える
1

Stringメソッドを使用したソリューションは、さまざまな理由であまり良くありません。いくつかは美的理由であり、他は実用的です。

実際の面では、(最初​​の例で表現したように)通常の形式よりも多くのオブジェクトがStringバージョンによって作成されます。

美的観点から言えば、2番目のバージョンはコードの意図を曖昧にしていると思います。これは、希望する結果を生成するためにコードを取得するのとほぼ同じくらい重要です。

于 2008-09-05T14:56:13.173 に答える
0

上記のツールキットの回答は正しく、最良の方法ですが、何が起こっているのかを完全に説明するものではありません。Java 5 以降の場合:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20

知っておく必要があるのは、これは次のこととまったく同じであるということです。

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20

オブジェクト 'a' に対して操作 (この場合は *=) を実行すると、'a' オブジェクト内の int 値が変更されるのではなく、実際に新しいオブジェクトが 'a' に割り当てられます。これは、乗算を実行するために「a」が自動ボックス化解除され、乗算の結果が自動ボックス化されて「a」に割り当てられるためです。

整数は不変オブジェクトです。(すべてのラッパー クラスは不変です。)

たとえば、次のコードを見てください。

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}

出力は次のようになります。

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520

「i」のメモリ アドレスが変化していることがわかります (メモリ アドレスは異なります)。

次に、リフレクションで少しテストを行い、これを test() メソッドの最後に追加します。

System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
    final Field f = i.getClass().getDeclaredField("value");
    f.setAccessible(true);
    f.setInt(i, 15);
    System.out.println("Step3: " + i.intValue());
    System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
    e.printStackTrace();
}

追加の出力は次のようになります。

MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520

リフレクションを使用して値を変更しても、「i」のメモリ アドレスは変更されていないことがわかります。
(実生活でこのように反射を使用しないでください!!)

于 2014-06-18T08:54:57.930 に答える