質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

6回答

2657閲覧

javaの再利用について

masaomi_ken

総合スコア20

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

3クリップ

投稿2016/01/25 04:57

編集2016/01/25 05:16

javaの質問です。

mport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Answer{

public static void main(String[] args) throws IOException { int a,b,answer,sum=0,tmpnum=0; double avg=0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("一つ目の数字"); String str = br.readLine(); a = Integer.parseInt(str); System.out.println("二つ目の数字"); String str2 = br.readLine(); b = Integer.parseInt(str2); System.out.println("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); String c = br.readLine(); switch(c){

case "1":
case "Max":
case "2":
case "Min":

if(a <= b){ tmpnum = b; b = a; a = tmpnum; System.out.println(a); } if(c.equals("1") || c.equals("Max")){ answer = a; System.out.println(anser); } else{ answer= b; System.out.println(anser); } break;

結果としては
10
20
MAX
20

と言った流れです。

数値は2回だけ入力し区分のMAXor最大値の時と
MINor最小値で大きい数を出すか小さい数を出す
か判別するプログラムです。

上のプログラムではa.bの入力された数値を交換しているですが、先生からプログラムの再利用性
を考えてと言われよく分からない状態です。

最初に数値を2つ打たせ次の区分で最大値かMAXとキーボードから打たれたら数値の大きい方を表示し、最小値かMINだった場合は数値の小さい方を出すプログラムがあるとします。

2つのロジックは似たようなものになるので記述を再利用性を考えてまとめるとしたらどのようにコードを書いたらいいのでしょうか⁇

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

java.lang.Mathのmax()やmin()などを自分で実装するような感じにすればいいと思います。

Java

1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4 5public class Answer{ 6 7 static String readString(String caption) throws IOException { 8 System.out.println(caption); 9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 10 return br.readLine(); 11 } 12 13 static int readInteger(String caption) throws IOException, NumberFormatException { 14 return Integer.parseInt(readString(caption)); 15 } 16 17 static int max(int a, int b) { 18 return a < b ? b : a; 19 } 20 21 static int min(int a, int b) { 22 return a < b ? a : b; 23 } 24 25 public static void main(String[] args) throws IOException, NumberFormatException { 26 int a = readInteger("一つ目の数字"); 27 int b = readInteger("二つ目の数字"); 28 String c = readString("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); 29 switch (c) { 30 case "1": 31 case "Max": 32 System.out.println(max(a, b)); 33 break; 34 case "2": 35 case "Min": 36 System.out.println(min(a, b)); 37 break; 38 } 39 } 40}

投稿2016/01/25 11:50

Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

テストのしやすさも加味してみました。
ここでは、いくつかの例を main() 中に書いていますが、
junit でテストケースを書くのが本来のテストの書き方になります。

min, max だけでなく、average(平均), add(足し算), sub(引き算) などの
処理の追加もしやすくなることも考慮しています。

java

1// See https://teratail.com/questions/25569 2 3import java.io.BufferedReader; 4import java.io.IOException; 5import java.io.InputStreamReader; 6 7class Comp { 8 public int min(int a, int b) { 9 return (a < b) ? a : b; 10 } 11 12 public int max(int a, int b) { 13 return (a < b) ? b : a; 14 } 15 16 public int add(int a, int b) { 17 return a + b; 18 } 19 20 public int sub(int a, int b) { 21 return a - b; 22 } 23 24 public int calc(String func, int a, int b) { 25 switch (func) { 26 case "2": 27 case "min": 28 return min(a, b); 29 case "1": 30 case "max": 31 return max(a, b); 32 default: 33 throw new IllegalArgumentException(func); 34 } 35 } 36} 37 38public class Answer { 39 40 static String readString(String caption) throws IOException { 41 System.out.println(caption); 42 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 43 return br.readLine(); 44 } 45 46 static int readInteger(String caption) throws IOException, NumberFormatException { 47 return Integer.parseInt(readString(caption)); 48 } 49 50 public static void main(String[] args) throws IOException, NumberFormatException { 51 Comp comp = new Comp(); 52 53 int a = readInteger("一つ目の数字"); 54 int b = readInteger("二つ目の数字"); 55 String func = readString("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); 56 System.out.println(comp.calc(func, a, b)); 57 58 // 簡易テスト 59 String[][] TESTS = { 60 { "max", "1", "2", "2" }, 61 { "max", "1", "1", "1" }, 62 { "1", "1", "2", "2" }, 63 { "min", "1", "2", "1" }, 64 { "min", "1", "1", "1" }, 65 { "2", "1", "2", "1" } 66 }; 67 for (String[] test : TESTS) { 68 int ans = comp.calc(test[0], Integer.parseInt(test[1]), Integer.parseInt(test[2])); 69 if (Integer.parseInt(test[3]) != ans) { 70 System.out.println("### Fail test:" + String.join(", ", test)); 71 } 72 } 73 } 74}

calc() 中の case 文はもっと工夫が可能です。
c/c++ での関数ポインターのようなものをにして
{"min" , finc_min} のように文字列の関数名と実際の java のメソッドを結びつけることで
case での分岐は、配列から関数名を探す処理に置き換えるのです。

投稿2016/01/31 15:06

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Stripeさんがご回答されたコードが秀逸です。

「再利用できるように」と言われても、何をどうすれば良いかイメージしずらいですよね。。。

以下のことを意識してみてください。

まず達成すべき処理がありますね。
「2つの数値と1つの文字の入力を受け、文字の区分によって最大値または最小値を出力する」

①この処理に必要であろう「単純な一つの仕事をする処理」を考えます。
おおむね、以下の機能があれば実装できそうですね。

・数値入力を受ける
・文字入力を受ける
・最大値を求める
・最小値を求める

②細分化したら、この機能のインターフェース(引数と戻り値)を考えます。

・数値入力を受ける機能 → 引数なし、数値を返却
・文字入力を受ける機能 → 引数なし、文字列を返却
・最大値を求める機能 → 引数は数値2つ、数値を返却
・最小値を求める機能 → 引数は数値2つ、数値を返却

インターフェースは内部の処理に関係ないデータまで含んだ配列やMapを渡すなど、
乱暴に設計してはいけません。
「必要なものを、必要なだけ」「できるだけ数値または文字列で」が指針の一つですが、そうはいかない
事も多々あります・・・

このように分析して、分解された「単純な一つの仕事をする処理」を、それぞれ実装します。
場合によっては、この処理単体でテストもします。

処理一つ一つがテストされて、ばっちり動くことが保障されたら、これらの機能を利用して、mainで目的の処理を記述します。

Stripeさんのコードは、まさにこのような書き方になっています。

よく細分化され、インターフェースがスッキリしていると、再利用性が高まります。

例えば、「数値入力を受ける」メソッドは、同じプログラムでまた入力が必要になった場合、
このメソッドを呼ぶだけですぐ再利用できます。
全く別のプログラム書くときは、参照して利用しても良いですし、コピペしたってそのまま使えます。

これは、各メソッドが「単純な一つの仕事をする処理」になっていて、かつ「インターフェースがスッキリ」しているからこそ成せるのです。

※前者を「凝集度」、後者を「結合度」という測り方で評価する方法があります。慣れてきたら勉強すると良いです。

この恩恵は再利用ができるだけではありません。

「単純な一つの仕事をする処理」に分けられていれば、メソッド名も付けやすくなります。
(メソッド名が付けずらい場合は、2つ以上の仕事がその中に入っている可能性が大です)

各メソッドが、このように単純な一つの仕事をする処理にスッキリとまとまっていると、
なにより、mainロジックの手続き処理の見通しが良くなります。

mainロジックの手続きがはっきり見通せるプログラムは、とっても読みやすいです。
そのため保守効率も、改修効率も上がります。

Stripeさんのコードをもう一度よくご覧になり、良く分析して理解されることをお勧めします。

投稿2016/01/25 17:04

編集2016/01/25 17:09
Toyoshima

総合スコア422

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

再利用のための、コードを書くためには、まず再利用ができないコードが書ける必要があります。慣れてくれば、書く前にどのようなコードになるかわかるので、再利用を意識したコードを直接書くようになります。慣れていない場合は、いきなり再利用できるようにすると余分なものまで再利用できるようにしてしまいますので順を追って再利用可能なコードに仕上げる必要があります。

始めは、再利用を考えずに書きます。

単純すぎますが、例えばこんなコードがあったとして

java

1int i = 2 + 1; 2System.out.println(i);

これがきちんと動作することが前提になります。

再利用したいコードがこうだっだとします。

java

1int j = 3 + 1; 2System.out.println(j);

違う部分を変数にします。

java

1int k = 2; 2int i = k + 1; 3System.out.println(i);

問題なく動作するか確認します。

これを関数に変えます。

java

1private void someMethod(int k){ 2 int i = k + 1; 3 System.out.println(i); 4}

このメソッドに名前を付けます。
そうですね、1を足してプリントするメソッドなので・・・

java

1private static void printAddOne(int k){ 2 int i = k + 1; 3 System.out.println(i); 4}

再利用します。

java

1printAddOne(2); 2printAddOne(3);

うまく動きますか?

足したものを表示するって、なんか分かりずらいですね。(と考えたとします。)
表示する部分はちゃんと見せたほうがわかりやすいかも・・・

java

1System.out.println(addOne(2)); 2System.out.println(addOne(3));

じゃあメソッドのほうも修正しましょう。

java

1private static int addOne(int k){ 2 int i = k + 1; 3 return i; 4}

また、動作を確認します。

このように、まず動くものを作ってちょっと修正して、確認してを繰り返すとだんだん再利用しやすいコードがかけるようになります。

投稿2016/01/25 10:50

編集2016/01/25 11:04
iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

大きいほうを希望するのなら"最大値"か"MAX"、小さいほうを希望するのなら"最小値"か"MIN"と入力させるのでしょうか??

標準入力等で入力するのは
"数値1" "数値2" "最大値/MAX/最小値/MIN"
ということですかね??

あまり長い処理にはならないと思うので記述の再利用性・・・というのもなんですが、
↑のように入力されるとしたら、↓をメソッド化して

long ans = 0; if(args[2]が"最大値"または"MAX"){ ans = Math.max()で比較 }else if(args[2]が"最小値"または"MIN"){ ans = Math.min()で比較 } ans を出力

みたいな感じでしょうか。
適宜、入力値チェックや型変換などを行ってください。

投稿2016/01/25 05:28

kaputaros

総合スコア1844

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaputaros

2016/01/25 05:32

すいません、ソースが後から乗ったんですね。 でも、まあ考え方は同じだと思います。 簡単な計算などは、java.lang.Mathクラスにそろってますよ。
masaomi_ken

2016/01/25 05:43

すみません書き忘れてしまっていたのですがmath関数は使うなと言われてしまい、試行錯誤していたのですが再利用を考えろと言われて困っています
guest

0

こんにちは。

コンソールからの入力になるので、入力文字は全てstring型で受け取れます。
したがって、以下のようなメソッドを作って対応してみてはいかがでしょう?
数値に限らず、引数で渡した文字列を辞書順で比較し、小さいほう又は大きいほうを受け取れます。
※数字だけに限らず、文字列も大小を判別できるので、やや汎用的かな?

public static String returnMinValue( String val1 , String val2 ){
if( val1.compareTo( val2 ) < 0 ){
return val2;
}else{
return val1;
}
}

public static String returnMaxValue( String val1 , String val2 ){
if( val1.compareTo( val2 ) < 0 ){
return val1;
}else{
return val2;
}
}

case:"1"
case:"Max"
に対しては、returnMaxValueを。

case:"2"
case:"Min"
に対しては、returnMinValueを。

いかがでしょう?
※caseの区切りにbreak;するのを忘れないでね!

あと、入力チェックが実装されていないようなので、
余力があれば入れてみてください。
※1,Max,2,Min以外の入力があった場合への対応など。

投稿2016/01/25 05:06

編集2016/01/25 05:30
hentai_nabe

総合スコア94

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaomi_ken

2016/01/25 05:40

1回やってみます‼︎丁寧なコメントありがとうございます‼︎
Stripe

2016/01/25 11:39

文字列の比較だと正しい結果が出ません。 ちゃんと、整数に変換してから比較してください。 例: "100" < "12" = true
hentai_nabe

2016/01/26 01:14

Stripeさん、コメントありがとうございます。 確かにおっしゃる通りですね。不覚。 入力された文字が、二つとも数字の場合のみ、 整数変換して比較してあげる処理が必要ですね。 > if( NumberUtils.isDigit(a) && NumberUtils.isDigit(b) ){ //整数変換して比べる。 }else{ //文字同士の辞書順で比べる。 } これで対応できますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問