Javaのコードに関しての質問なのですが、以下の二つで違いが出るのかがわからず、それを調べる方法もわかりません。
return value + "";
と
return "" + value;
です。
ソースコードでは、valueはもともとIntで値が与えられていて、if文を使いStringにして返すというメソッドでの一文です。
上の二つに違いはあるかという問題にぶつかり、解き方がわからずに困っています。
説明のなど至らない点があると思いますが、ご回答いただければ嬉しいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/03 04:05
回答4件
0
質問文のコードは試してもらうとして、
以下の場合でもどうなるか試してみると良いですね。
return "" + value + 10;
return value + 10 + "";
考えるべきところは
int + int → int
int + String → ?
String + int → ?
String + int + int → ? + int → ?
int + int + String → int + String → ?
これらの?がそれぞれどうなるか、という感じですね。
投稿2019/10/03 04:45
総合スコア5158
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
誰もやろうとしないので、以下のプログラムを使って実行時間を実測してみました。
Java
1import java.util.stream.IntStream; 2import java.util.function.IntConsumer; 3import java.util.Arrays; 4 5public class TestStr { 6 public static void main(String... args) { 7 final var max = Integer.parseInt(args[0]); 8 final var count = Integer.parseInt(args[1]); 9 final var num = Integer.parseInt(args[2]); 10 System.out.println("数の幅: 0 - " + max); 11 System.out.println("繰り返し数: " + count); 12 System.out.println("サンプル数: " + num); 13 final var bs = new long[num]; 14 final var as = new long[num]; 15 // 一回目は切り捨て 16 for (int n = 0; n < num; n++) { 17 bs[n] = benchmarkNanoSec(max, count, i -> { 18 intToStrBeforeString(i); 19 }); 20 as[n] = benchmarkNanoSec(max, count, i -> { 21 intToStrAfterString(i); 22 }); 23 } 24 // 二回目本番 25 for (int n = 0; n < num; n++) { 26 bs[n] = benchmarkNanoSec(max, count, i -> { 27 intToStrBeforeString(i); 28 }); 29 as[n] = benchmarkNanoSec(max, count, i -> { 30 intToStrAfterString(i); 31 }); 32 } 33 34 System.out.printf("文字列の前 平均: %.2f ms\n", Arrays.stream(bs).average().orElse(0) / 1000 / 1000); 35 System.out.printf("文字列の後 平均: %.2f ms\n", Arrays.stream(as).average().orElse(0) / 1000 / 1000); 36 } 37 38 public static String intToStrBeforeString(int value) { 39 return value + ""; 40 } 41 42 public static String intToStrAfterString(int value) { 43 return "" + value; 44 } 45 46 public static long benchmarkNanoSec(int max, int count, IntConsumer f) { 47 final var startNanoTime = System.nanoTime(); 48 for (int i = 0; i < count; i++) { 49 IntStream.range(0, max).forEach(f); 50 } 51 final var endNanoTime = System.nanoTime(); 52 return endNanoTime - startNanoTime; 53 } 54}
BellSoftのLiberica JDK 11.0.5(openjdk version "11.0.5-BellSoft" 2019-10-15) 64bit Windowsでの結果は下記になりました。
text
1数の幅: 0 - 100000 2繰り返し数: 1000 3サンプル数: 5 4文字列の前 平均: 1113.83 ms 5文字列の後 平均: 1117.35 ms
誤差の範囲と言ってもいいぐらいほぼ一緒です。Liberica JDK 11についてはパフォーマンスについて違いは無いと言っていいと思います。他のJDK実装や過去のバージョンは確認していません。古い(1.4ぐらい?)Javaだと文字列結合にStringBufferを使っていたりしていて、今とはコンパイル後のコードが異なるらしいので、違いは出るかも知れません。
投稿2019/10/30 11:37
総合スコア21735
0
ベストアンサー
演算子の言語仕様について知りたいので、「java 演算子 仕様」あたりで検索します。
こちらのページが見つかりました。
http://www.y-adagio.com/public/standards/tr_javalang/15.doc.htm#15746
- 演算子のいずれかのオぺランドの型がStringならば,演算は文字列の連結とする。
および
一つのオペランドの式だけが型Stringならば,実行時に文字列を生成するために,他方のオペランドに対して文字列変換を実行する。
とあるので、どちらの場合も同じくvalueはStringに変換されるようです。
結果は二つのオペランドの文字列を連結して新たに作成したオブジェクト String への参照とする。
とあるので、(どちらかのオブジェクトが残るのでなく)両オペランドとは無関係なオブジェクトとなり違いは生じなさそうです。
あとは空文字列と空でない文字列を連結した時に順序によって何か違いが生じるかですが、普通に考えて違いは無さそうな気はするものの確信が持てません。
投稿2019/10/03 15:58
総合スコア3047
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/17 01:38
2019/10/17 02:49
2019/10/17 13:29
2019/10/17 13:36
2019/10/17 13:59
2019/10/17 14:08
2019/10/17 14:21
2019/10/17 14:26 編集
2019/10/17 14:58
2019/10/17 15:02 編集
2019/10/30 12:54
2019/10/30 13:32
2019/10/30 15:56
2019/10/30 15:59
2019/10/30 16:34
2019/10/30 21:02
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。