Javaで「Integer」オブジェクトに10を掛けるにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/45964

  •  09-06-2019
  •  | 
  •  

質問

10 を 1 に掛けるにはどうすればよいですか Integer 反対して取り返してください Integer 物体?

これを行う最もきちんとした方法を探しています。

私はおそらく次のようにするでしょう:int の取得元 Integer オブジェクトを作成し、それを他の int と乗算し、この int 値を持つ別の Integer オブジェクトを作成します。

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

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

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

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

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

どちらにしてもやるメリットはあるのでしょうか?

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

役に立ちましたか?

解決

Java 5 の場合 オートボクシング, 、次のようにするだけで済みます。

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

他のヒント

文字列のアプローチは面白いですが、ほぼ確実に悪い方法です。

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

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

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

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

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

    (s1 == s2) だろう false, 、 その間 s1.equals(s2) だろう true.

  • Integer.parseInt 内部呼び出し new Integer() とにかく、なぜなら Integer は不変です。

ところで、自動ボックス化/ボックス化解除は内部的には最初の方法と同じです。

2 番目のアプローチは避けてください。Java 1.5 を使用している場合、最善の方法はオートボックス化です。最初の例より前のものが最適です。

String メソッドを使用した解決策は、さまざまな理由からあまり適切ではありません。美的な理由もあれば、実用的な理由もあります。

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

美的観点から言えば、2 番目のバージョンではコードの意図がわかりにくくなっており、それはコードで目的の結果を生成することと同じくらい重要だと思います。

上記のツールキットの答えは正しく、最良の方法ですが、何が起こっているのかを完全に説明していません。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」のメモリ アドレスは変更されていないことがわかります。
(実生活ではこのように反射を使用しないでください!!)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top