blue-phoenix
@blue-phoenix

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

if文の簡略化について

if文についてお聞きしたい事があります。
javaを始めて基本的な問題を書き続けてゆく内、
最近になってから記述の簡素化を意識して色々なコードの行を減らしています。
学習量も増えて今まで学んだ事だけ書いてきてもどうやら無駄も増えてきて、
そういった中で行喰いの1つであるif文もどうにか縮めたくて今回書きました。

Nが 100 以下の場合はYESを、そうではない場合はNOを出力。
System.out.println(sc.nextInt() <= 100) ? "YES" : "NO";

といった書き方で1行締めにして紙にプリンターしてコストを減らしています。
こちらで教わった省略法に気づいてから一度意識し直していて、
こういったYES,NOや1、0などの二択の場合はそれで書けますが、
例えば以下の様な複数の出力がある時は三項演算子の様な簡略化した文は使えないのでしょうか?

九九
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
System.out.print(i * j);
if (j < 9) {
System.out.print(" ");
} else {
System.out.println();
}}}

整数入力5行
int n = sc.nextInt();

if (n >= 1) {
  System.out.println(1);
}
if (n >= 2) {
  System.out.println(2);
}
if (n >= 3) {
  System.out.println(3);
}
if (n >= 4) {
  System.out.println(4);
}
if (n == 5) {
  System.out.println(5);
}

九九などの数値や文字が入っていない改行的出力。
nがそれ以上の数の時、その数をままに出力する場合。
今回内容詳細は特にお尋ねしませんが、ifの数だけ長くてどうにか
簡略化できないかと悩んでいます。右にずらせば良いと指摘されれば
それまでですが、同じものが数十もあったら大変で。行数の食いすぎるコードは
いずれどこかでミスをしてランタイムエラーも発生させてしまうので。
もしあるのでしたら御教授お願いします。

0

3Answer

まず質問文のコードに誤りがあるので,先んじて指摘します.

Wrong
System.out.println(sc.nextInt() <= 100) ? "YES" : "NO";
                                      ^
Correct
System.out.println(sc.nextInt() <= 100 ? "YES" : "NO");

三項演算子は通常値を返す部分に対して使用されるものです.値を返さない単純な処理分岐に対しては可読性を下げるため,使用を推奨されることは多くありません.開発現場においては,三項演算子を禁止する場合があるため,コードの記述量を減らすためだけに三項演算子を使用することはあまり良い習慣ではありません.

行数の食いすぎるコードはいずれどこかでミスをしてランタイムエラーも発生させてしまうので。

むしろ長さを詰めに詰めたコードは論理破綻を起こしやすく,ランタイムエラーやエラーコードを返さないバグも生じやすくなります.読めないコードはIDEのデバッグツールを以てしても問題の特定を困難にします.
ランタイムエラーやバグを減らしたい場合,通常は可読性の確保を最優先にすべきです.保守性を確保しなければならないときにコードを短くすることは,多くの場合で間違った方策です.

初心者の方はおとなしくifを書くことを強く推奨します.通常の使用例において,if文の多さがパフォーマンスに無視できない影響を与えることはほとんどありません.どうしても条件分岐が多くなりすぎる場合は,switch-caseの使用や,ロジックの見直しをまず検討してください.

3Like

Comments

  1. そもそも別に三項演算子を使ったところで

    for (int i = 1; i < 10; i++) {
      for (int j = 1; j < 10; j++) {
        System.out.print("" + (i*j) + (j < 9 ? " " : ""));
      }
      System.out.println();
    }
    

    ぐらいの簡略化しかできないと思います.
    下の例に関しては三項演算子を無理に使うとロジックを壊してしまうため,ifで書くのがもっともシンプルと言えます.いいとこ{}を省略することはできますが,それ以上短くしようとするとどうやっても見づらくなるでしょう.

  2. @blue-phoenix

    Questioner

    な、なるほど・・・省きすぎても返ってエラーが発生してしまうとは。
    自分としてはこちらの方が見やすいと思うのですがデバッグに引っかかるとは、
    あまりにも行が増えてきてウンザリしていたものでつい。
    switch-caseですか、とにかくこれを参考にしていきます。
    Ver先生、いつもありがとうございます!

  3. switch-caseも特にフォールスルーの使用に関して現場レベルで制限することがあるので注意してください.break忘れはIDEが通常指摘しないので,バグの温床となりやすいためです.
    一応こんな風には書けますが推奨はしません.

    switch(n) {
    case 5:
      System.out.println(5);
    case 4:
      System.out.println(4);
    case 3:
      System.out.println(3);
    case 2:
      System.out.println(2);
    case 1:
      System.out.println(1);
      break;
    }
    

冒頭の文章を読んでswitch式を聞きたいのかと思ったのですが、後半で何をしたいかがわからなくなりました。

例えば以下の様な複数の出力がある時は三項演算子は使えないのでしょうか?

これ、何をしたいのかもう少し具体的に言葉で表現できませんか?

0Like

Comments

  1. @blue-phoenix

    Questioner

    誤解を招く書き方をしてしまったようです、三項演算子"みたいに"シンプルに記述できる方法が知りたいだけです。必ず三項でなければならない理由ではないので他の記述でもOKです。

  2. 複数の出力がある場合でも、コードの簡略化が可能な場合があります。ただし、三項演算子は基本的に二択の場合に適しています。しかし、他の方法でコードを短くすることができます。

    九九の例であれば、System.out.print()とSystem.out.println()を組み合わせて1行にすることができます。以下のように書くことができます。

    Copy code
    for (int i = 1; i < 10; i++) {
        for (int j = 1; j < 10; j++) {
            System.out.print(i * j + (j < 9 ? " " : "\n"));
        }
    }
    

    整数入力5行の例については、forループを使ってコードを簡略化できます。

    Copy code
    int n = sc.nextInt();
    for (int i = 1; i <= n && i <= 5; i++) {
        System.out.println(i);
    }
    

    このように、三項演算子以外の方法でもコードの簡略化が可能です。構造を工夫することで、if文の数を減らし、コードをシンプルにすることができます。

  3. @blue-phoenix

    Questioner

    ケショオオオォ、for文の中に&&を!?
    九九もあんなに長かったものがこんなに短くできるとはァ。
    こんな方法があるとは・・・本当にコードの世界はバリエーションが多くて。
    でもこれで一区切りできたような気がします、しばらくは整理の時期ですね。
    ここまで教えてもらったからには10年は続けようと思います。
    tama先生、ありがとうございました!

コードの行が多いので減らしたいというのはまっとうな感覚ですが、そうしたい動機として2つの問題があると思います。

  • 視覚的に量が多くてわかりにくい
  • やるべき処理が多くてわかりにくい

コードの行数を減らしたい、というのは視覚的な量に対して解決したいのだと見受けられます。しかし視覚的な量だけを減らしても、もう片方の問題は解決しません。

例えば日本語の文章でも、行を削って量を減らした結果、正確に伝わらなくなってしまっては本末転倒です。プログラミングにおいてそれは、コードが理解しづらくなったり、バグが発生したりすることになります。
ですので、処理の目的についても注目する必要があります。

例えば、「整数入力5行」が「1から入力された整数(最大5)まで順に出力したい」ということであれば、for文などのループを使った方法が考えられます。(すでに提案されてる例にあります)

0Like

Comments

  1. @blue-phoenix

    Questioner

    確 に、記述を省きす ても何を言っ るのか分かりに なりま ね。
    コードを リントして壁に貼っ 覚えていま が、特にif文が行  してきて。
    時には素の状態 しろ、それ 念頭に置いて  ます。

Your answer might help someone💌