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

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

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

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

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

Q&A

解決済

4回答

680閲覧

「List<JavaBeans>」型を返却するメソッドを作りたい

退会済みユーザー

退会済みユーザー

総合スコア0

JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

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

0グッド

0クリップ

投稿2022/07/23 02:48

前提

Junitにて色々なBeanのListデータが必要になりました。
しかし、Beanの型は異なるけど、「Beanを生成して特定のフィールド値を設定する。それをListに詰める。」は同じで、似たような処理を書くのは面倒くさいです。
なので、「List<JavaBeans>」型を返却するメソッドを作成することにしました。

実現したいこと

対象Bean名で分岐させ各々で処理する方法を思いつきましたが、対象Beanが増えるとその分を追記しなければなりません。そこで、for文の箇所を共通化する方法はありますか?

該当のソースコード

実施環境に今いないので、思い出しながら下記ソースを書きました。
なので、正確ではないことはご了承ください。

// List作成メソッド (arrayがリストに詰めるためのデータ) public List<T> createList(Class<T> clazz, String[] array){ // 戻り値 List<T> list = new ArrayList<>(); // 名前によって分岐 switch (clazz.getSimpleName()) { case "ABean": // ABeanの場合 for (String s: array) { ABean bean = new ABean(); bean.setName(s); list.add(clazz.cast(bean)); } break; case "BBean": // BBeanの場合 for (String s: array) { BBean bean = new BBean(); bean.setAddress(s); list.add(clazz.cast(bean)); } break; case default: break; } retrun list; } public class ABean () { private name; } public class BBean () { private address; }

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

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

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

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

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

jimbe

2022/07/23 05:44 編集

どのようなテストをしようとされているのか分かりませんが…。 JUnit のコードをヘタに複雑にすると、テスト対象の問題なのかテストコードの問題なのかが分かり難くなりそうです。 何でしたら(実行環境にいられましたら)、その「面倒くさい」と思われる程肥大化(?)してしまったコードをまず作ってみて、それをご質問に出してみては如何でしょうか。(100行程度もあれば十分かと。)
guest

回答4

0

ベストアンサー

リフレクションで setter を呼んじゃう、とかはどうですか。

Java

1 public static void main(String[] args) throws Exception { 2 3 String[] array = {"aaaa", "bbbb", "cccc"}; 4 5 List<ABean> aBeans = createList(ABean.class, "setName", array); 6 List<BBean> bBeans = createList(BBean.class, "setAddress", array); 7 } 8 9 public static <T> List<T> createList(Class<T> clazz, String setter, String[] array) throws Exception { 10 11 List<T> list = new ArrayList<>(); 12 13 for (String s : array) { 14 15 T bean = clazz.getDeclaredConstructor().newInstance(); 16 clazz.getMethod(setter, String.class).invoke(bean, s); 17 list.add(bean); 18 } 19 20 return list; 21 }

投稿2022/07/24 17:37

編集2022/07/24 18:03
momodx

総合スコア185

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

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

0

こんな風にも出来ますが…結局のところ for 文がその他のコードになるだけで、 "同じようなコードが並ぶ" ことには変わらないようにも思います。

java

1import java.util.ArrayList; 2import java.util.List; 3 4public class Main { 5 public static void main(String[] args) { 6 7 List<ABean> alist = getList(new String[]{"あ","い","う"}, s -> { 8 ABean bean = new ABean(); 9 bean.setName(s); 10 return bean; 11 }); 12 13 List<BBean> blist = getList(new String[]{"か","き","く"}, s -> { 14 BBean bean = new BBean(); 15 bean.setAddress(s); 16 return bean; 17 }); 18 19 System.out.println("alist="+alist); 20 System.out.println("blist="+blist); 21 } 22 23 interface Factory<T> { 24 T create(String s); 25 } 26 static <T> List<T> getList(String[] array, Factory<T> factory) { 27 List<T> list = new ArrayList<T>(array.length); 28 for(String s : array) list.add(factory.create(s)); 29 return list; 30 } 31} 32 33class ABean { 34 private String name; 35 void setName(String name) { this.name = name; } 36 @Override public String toString() { return name; } 37} 38class BBean { 39 private String address; 40 void setAddress(String address) { this.address = address; } 41 @Override public String toString() { return address; } 42}

実行結果

plain

1alist=[あ, い, う] 2blist=[か, き, く]

投稿2022/07/23 07:03

jimbe

総合スコア12632

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

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

0

雑ですがこんなのでどうでしょうか。
ラムダから型を取るのは大変らしいので、よくある可変長引数のtipsで^^;

Java

1import java.util.ArrayList; 2import java.util.List; 3import java.util.function.BiConsumer; 4 5public class Main { 6 public static void main(String[] args) { 7 var foo = createList(ABean::setName, new String[]{ "foo", "bar", "baz", }); 8 var hoge = createList(BBean::setAddress, new String[]{ "hoge", "fuga", "piyo", }); 9 } 10 11 @SuppressWarnings("unchecked") 12 private static <T> List<T> createList(BiConsumer<T, String> setter, String[] array, T... dummy) { 13 var list = new ArrayList<T>(); 14 var clazz = (Class<T>) dummy.getClass().getComponentType(); 15 16 try { 17 for (var s : array) { 18 var bean = clazz.getDeclaredConstructor().newInstance(); 19 setter.accept(bean, s); 20 list.add(bean); 21 } 22 } catch (ReflectiveOperationException e) { 23 throw new RuntimeException(e); 24 } 25 26 return list; 27 } 28} 29 30class ABean { 31 private String name; 32 33 public String getName() { return name; } 34 35 public void setName(String name) { this.name = name; } 36} 37 38class BBean { 39 private String address; 40 41 public String getAddress() { return address; } 42 43 public void setAddress(String address) { this.address = address; } 44}

投稿2022/07/23 06:55

TN8001

総合スコア9317

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

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

TN8001

2022/07/25 23:51

さすがに納得いかんなぁ。実用するなら一番いい実装だと思ったんだけどw 使う側の文字数も少なくて、文字列で指定するよりメソッド参照のほうが堅牢なのに... varがあかんかったんかなぁ?w(型を書けば8でも通るはず)
guest

0

各Beanによって処理が違いますし、fatになるだけです。
無理に共通化する方が冗長で分かりづらくなると思います。

元々呼び出し元も全然違うのですから、そのBeanだけを扱うクラス(モデルクラスになるかな?)
を作って呼び出し元にあわせたほうが良いです。なるべく疎結合に。

投稿2022/07/23 02:57

m.ts10806

総合スコア80850

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問