If you can dream it, you can do it.

元タイトル「北の大地のIT技術屋より」

Javaで同一IDのフィールドをマージする。

 

 

久しぶりにゴリゴリとJavaを書いている。

そんな中、以下の様な要件があってJavaで対応することになった。

 

今回のお題

 

①テーブル構造はidとnameのみで両方合わせて一意(PK)である

②同一idのnameをまとめてカンマ区切りで表示したい。

 

データの例としては以下のイメージ。

id name
1 ABC
1 DEF
2 ABC
3 ABC
3 DEF
4 ABC
5 ABC
6 ABC
7 ABC
7 DEF
7 GHI
8 ABC
8 ABC
9 ABC
10 ABC
10 DEF

 

これを以下のようにしたいのだ。

 

1 : ABC,DEF
2 : ABC
3 : ABC,DEF
4 : ABC
5 : ABC
6 : ABC
7 : ABC,DEF,GHI
8 : ABC,ABC
9 : ABC
10 : ABC,DEF

 

これのロジックを考えるのにハマったのだ。

 

考えた結果

 

できなかったのだけど、1つ1つ考えてみて整理した。

1.初回データは前回のデータとして保持する。

2.前回のデータとIDが同じ場合、nameを結合して追加

3.前のデータとIDが違う場合、前のデータを登録(結果として出力)する

4.最後のデータは登録(結果として出力)する

 

この考えてソースを書いてみた。

 

まず、データを保持しているItemBean.java。実質DBから取得したデータだと思ってもらいたい。

 

  1. public class ItemBean {
  2.     private int id;
  3.     private String name;
  4.     // コンストラクタ
  5.     public ItemBean(int id, String name){
  6.         this.id = id;
  7.         this.name = name;
  8.     }
  9.     public int getId() {
  10.         return id;
  11.     }
  12.     public void setId(int id) {
  13.         this.id = id;
  14.     }
  15.     public String getName() {
  16.         return name;
  17.     }
  18.     public void setName(String name) {
  19.         this.name = name;
  20.     }
  21. }

 

 

次に、結果を出力するためのResultBean.java

 

  1. public class ResultBean {
  2.     private int id;
  3.     private String name;
  4.     // コンストラクタ
  5.     public ResultBean(){
  6.     }
  7.     public int getId() {
  8.         return id;
  9.     }
  10.     public void setId(int id) {
  11.         this.id = id;
  12.     }
  13.     public String getName() {
  14.         return name;
  15.     }
  16.     public void setName(String name) {
  17.         this.name = name;
  18.     }
  19. }

 

 

最後に上記2つを使ったメインのロジックと出力クラス。

 

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Test1_1 {
  4.     /**
  5.      * @param args
  6.      */
  7.     public static void main(String[] args) {
  8.         // 登録されているデータ
  9.         List<ItemBean> dataList = new ArrayList<ItemBean>();
  10.         dataList.add(new ItemBean(1,"ABC"));
  11.         dataList.add(new ItemBean(1,"DEF"));
  12.         dataList.add(new ItemBean(2,"ABC"));
  13.         dataList.add(new ItemBean(3,"ABC"));
  14.         dataList.add(new ItemBean(3,"DEF"));
  15.         dataList.add(new ItemBean(4,"ABC"));
  16.         dataList.add(new ItemBean(5,"ABC"));
  17.         dataList.add(new ItemBean(6,"ABC"));
  18.         dataList.add(new ItemBean(7,"ABC"));
  19.         dataList.add(new ItemBean(7,"DEF"));
  20.         dataList.add(new ItemBean(7,"GHI"));
  21.         dataList.add(new ItemBean(8,"ABC"));
  22.         dataList.add(new ItemBean(8,"ABC"));
  23.         dataList.add(new ItemBean(9,"ABC"));
  24.         dataList.add(new ItemBean(10,"ABC"));
  25.         dataList.add(new ItemBean(10,"DEF"));
  26.         // 結果取得用のリスト
  27.         List<ResultBean> resultList = new ArrayList<ResultBean>();
  28.         ResultBean result = null;
  29.         ResultBean beforeResult = null;
  30.         for(ItemBean bean : dataList){
  31.             result = new ResultBean();
  32.             result.setId(bean.getId());
  33.             result.setName(bean.getName());
  34.             // 初回
  35.             if(beforeResult == null){
  36.                 // 前のデータとして保持
  37.                 beforeResult = result;
  38.             } else if(beforeResult.getId() == result.getId()){//前のIDと同じ時
  39.                 beforeResult.setName(beforeResult.getName() + "," + result.getName());
  40.             } else if(beforeResult.getId() != result.getId()){//前のIDと違う時
  41.                 // 前のデータを登録する
  42.                 resultList.add(beforeResult);
  43.                 // 前のデータとして保持
  44.                 beforeResult = result;
  45.             }
  46.         }
  47.         if(beforeResult != null){
  48.             resultList.add(beforeResult);
  49.         }
  50.         for(ResultBean rslt : resultList){
  51.             System.out.println(rslt.getId() + " : " + rslt.getName());
  52.         }
  53.     }
  54. }

 

この出力結果は想定通りとなっている。

 

 

1.初回データは前回のデータとして保持する。⇒41行目のif文

2.前回のデータとIDが同じ場合、nameを結合して追加 ⇒46行目のif文

3.前のデータとIDが違う場合、前のデータを登録(結果として出力)する ⇒48行目のif文

4.最後のデータは登録(結果として出力)する ⇒56行目のif文

 

前のデータの保持は回している中の最後にして、前のIDと同じときは値を設定したらcontinueするのも考えたけど、やりたいこととプログラムを一致させる意味で同じ処理を2回書いている。 

 

 

 

こんなんに時間使っているようではまだまだだぜ。

 

 

 こちらからは以上です。

 

スッキリわかるJava入門 第2版

スッキリわかるJava入門 第2版

 

 

12時間でわかるJ2EE実践ガイド (J2EE & BEA WebLogic Server)

12時間でわかるJ2EE実践ガイド (J2EE & BEA WebLogic Server)