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

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

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

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

Q&A

解決済

2回答

1134閲覧

Listに重複する名前があったら値を変えたい

moshi

総合スコア90

Java

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

0グッド

0クリップ

投稿2020/02/27 05:19

前提・実現したいこと

あるフォルダにあるファイル名を元にリストを作成したいです。
ファイル名は

20200227_0001_A.text

のようになっていて、(日付)(ID)(型).txtのように規則的につけられています。

フォルダに
・20200225_0001_A.txt
・20200226_0001_B.txt
・20200227_0001_A.txt
・20200227_0001_B.txt
・20200227_0002_A.txt
・20200227_0002_C.txt
とファイルがあった時に関する質問です。

該当のソースコード

public String ok() { List<TestInfoBean> list = new ArrayList<TestInfoBean>(); // ファイル置き場 String path = "C:\tmp\test\_test"; File dir = new File(path); File files[] = dir.listFiles(); // ファイル数分繰り返し for(int i=0; i<files.length; i++){ // ファイル名取得 String fileName = files[i].getName(); // ファイル名分割 String[] param = fileName.split("_"); // TestInfoBeanにセット TestInfoBean info = new TestInfoBean(); info.setHiduke(param[0]); info.setId(param[1]); String type = param[2].substring(0, 1); switch(type) { case "A": info.setTypeA(true); break; case "B": info.setTypeB(true); break; case "C": info.setTypeC(true); break; } list.add(info); } return "ok"; }
@Data public class TestInfoBean { private String hiduke; private String id; private boolean typeA; private boolean typeB; private boolean typeC; }

発生している問題・エラーメッセージ

今のままだとlistには6つの要素があるのですが
本当は日付とIDが同じだった場合のinfoを一つにまとめてlistに追加したいです。
例)
・20200227_0001_A.txt
・20200227_0001_B.txt
は日付とIDが同じのため

info.hidukeが20200227、 info.idが0001、 info.typeAがtrue、 info.typeBがtrue、 info.typeCがfalse

のように一つのinfoとして扱いたいです。(今回のファイルの場合、合計のlistの要素を4つにしたいです)

しばらく考えてはみたのですがどうやって比較すれば良いかがわからず…
わかる方がいたら教えてください。

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

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

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

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

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

jimbe

2020/02/27 09:12

ok メソッドの中で list は貯めるだけで使用されていませんが, List である必要はあるのでしょうか.
guest

回答2

0

簡単(?)には Map を使います.
一応最後に List に入れ直していますが, 必要無ければ map.values() を使えばよろしいかと思います.

java

1import java.io.File; 2import java.util.*; 3 4public class Q243809 { 5 6 public static void main(String[] args) { 7 ok(); 8 } 9 10 static class TestInfoBean { 11 private String hiduke; 12 private String id; 13 private boolean typeA; 14 private boolean typeB; 15 private boolean typeC; 16 void setHiduke(String s) { hiduke=s; } 17 void setId(String s) { id=s; } 18 void setTypeA(boolean f) { typeA=f; } 19 void setTypeB(boolean f) { typeB=f; } 20 void setTypeC(boolean f) { typeC=f; } 21 public String toString() { 22 return "[hiduke="+hiduke+",id="+id+ 23 ",typeA="+typeA+ 24 ",typeB="+typeB+ 25 ",typeC="+typeC+"]"; 26 } 27 } 28 29 public static String ok() { 30 31 Map<String,TestInfoBean> map = new HashMap<>(); 32 33 // ファイル置き場 34 String path = "C:\tmp\test\_test"; 35 //String path = "tmp"; 36 File dir = new File(path); 37 File files[] = dir.listFiles(); 38 // ファイル数分繰り返し 39 for(int i=0; i<files.length; i++){ 40 // ファイル名取得 41 String fileName = files[i].getName(); 42 // ファイル名分割 43 String[] param = fileName.split("_"); 44 45 TestInfoBean info = map.get(param[0]+"_"+param[1]); 46 if(info == null) { 47 info = new TestInfoBean(); 48 info.setHiduke(param[0]); 49 info.setId(param[1]); 50 map.put(param[0]+"_"+param[1], info); 51 } 52 53 String type = param[2].substring(0, 1); 54 switch(type) { 55 case "A": 56 info.setTypeA(true); 57 break; 58 case "B": 59 info.setTypeB(true); 60 break; 61 case "C": 62 info.setTypeC(true); 63 break; 64 } 65 } 66 67 List<TestInfoBean> list = new ArrayList<>(map.values()); 68 69 for(TestInfoBean info : list) System.out.println(info); 70 71 return "ok"; 72 } 73}

plain

1[hiduke=20200225,id=0001,typeA=true,typeB=false,typeC=false] 2[hiduke=20200227,id=0001,typeA=true,typeB=true,typeC=false] 3[hiduke=20200227,id=0002,typeA=true,typeB=false,typeC=true] 4[hiduke=20200226,id=0001,typeA=false,typeB=true,typeC=false]

投稿2020/02/27 09:31

jimbe

総合スコア12646

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

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

0

ベストアンサー

特に指定がなかったですがjava8対応の書き方です。
continueラベルとか使ってて美しくはありませんが・・・。

java

1List<TestInfoBean> list = new ArrayList<TestInfoBean>(); 2 3// ファイル置き場 4String path = "C:\tmp\test\_test"; 5File dir = new File(path); 6File files[] = dir.listFiles(); 7// ファイル数分繰り返し 8file_loop: for(int i=0; i<files.length; i++){ 9 // ファイル名取得 10 String fileName = files[i].getName(); 11 // ファイル名分割 12 String[] param = fileName.split("_"); 13 14 Consumer<TestInfoBean> setType = info -> { 15 String type = param[2].substring(0, 1); 16 switch(type) { 17 case "A": 18 info.setTypeA(true); 19 break; 20 case "B": 21 info.setTypeB(true); 22 break; 23 case "C": 24 info.setTypeC(true); 25 break; 26 } 27 }; 28 29 // リストをループする 30 for (TestInfoBean info : list) { 31 // 日付とID両方が一致する場合 32 if (info.getHiduke().equals(param[0]) 33 && info.getId().equals(param[1])) { 34 // リスト内のTestInfoBeanにTypeを設定 35 setType.accept(info); 36 // ファイルループに戻って処理を繰り返す 37 continue file_loop; 38 } 39 } 40 41 // TestInfoBeanにセット 42 TestInfoBean info = new TestInfoBean(); 43 info.setHiduke(param[0]); 44 info.setId(param[1]); 45 setType.accept(info); 46 47 list.add(info); 48} 49 50// リスト内の確認(デバッグコード) 51list.forEach(l -> 52 System.out.println( 53 "hiduke=" + l.getHiduke() + 54 "、id=" + l.getId() + 55 "、typeA=" + l.isTypeA() + 56 "、typeB=" + l.isTypeB() + 57 "、typeC=" + l.isTypeC()));

投稿2020/02/27 07:14

yureighost

総合スコア2183

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

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

moshi

2020/02/27 09:09

回答ありがとうございます。 上記でやりたいことはできました。助かります。 もし可能であれば少し教えていただきたいのですが Consumer<TestInfoBean> setType = info -> { と setType.accept(info); のところは何をしているのでしょうか・・・調べてみたけどよくわからなく・・・ continue file_loop;はfile_loopと名前を付けたループ処理にcontinueするというのはわかるのですが お時間ありましたら回答お願いします
yureighost

2020/02/27 09:29

その辺りのコードはJava8で追加されたメソッドを変数として定義できる機能です。 Consumerは引数を1つ取りつつ返り値は返さない。 メソッドで言うとvoid型の物と同等になります。 acceptはその定義した変数の処理を実行するメソッドです。 「java8 関数型インターフェース」などで検索すると解説してるサイトがありますので調べてみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問