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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Collections API

Collections APIは開発者に複数のクラスやインターフェイスを供給し、多くのオブジェクトを扱いやすくします。

Java

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

Q&A

解決済

2回答

1783閲覧

テキストファイルからArrayListに内容を取り込み、その情報をソートして表示させたいです

chahahaan

総合スコア1

Collections API

Collections APIは開発者に複数のクラスやインターフェイスを供給し、多くのオブジェクトを扱いやすくします。

Java

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

1グッド

0クリップ

投稿2022/12/28 12:42

前提

Javaの質問です。

Javaでプログラミングを勉強し始めて3週間と少しのド初心者です。クラスやオブジェクト指向の概念など基本的なことは一通り学んだつもりですが少しでも応用的な内容になるとかなり苦戦してしまいます。
恐縮ですがご助力いただけますと幸いです。

名簿としてID番号、名前、生年月日、性別を記載したテキストファイル(プロジェクト直下に作成)をArrayListに取り込み、ソートしてコンソールに一覧表示するプログラムを書いています(未完)。
ArrayListへのテキストファイルの取り込みと、ソートしないファイルそのままの状態での一覧表示までは試行錯誤の末なんとかできるようになりました。
その次の段階でID、名前、生年月日などでソートし名簿を昇順や降順で表示をさせたいのですが、コンパイルエラーの出ないプログラムがどうしてもうまく書けません。

実現したいこと

・テキストファイルをArrayListへ取り込み、その内容をID、名前、生年月日などでソートしコンソールへ一覧表示させたいです。
・どのようにコードを書き換えれば正常に動作するようになるか知りたいです。

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

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 型 MemberComparator は継承された抽象メソッド Comparator.compare(Object, Object) を実装する必要があります

該当のソースコード

Java

1import java.io.BufferedReader; 2import java.io.File; 3import java.io.FileNotFoundException; 4import java.io.FileReader; 5import java.io.IOException; 6import java.util.ArrayList; 7import java.util.Collections; 8 9public class SortTest { 10 11 public ArrayList<SortBean> sortbeanArray = new ArrayList<SortBean>(); 12 13 public static void main(String[] args) { 14 SortTest st = new SortTest(); 15 st.read(); 16 st.show(); 17 } 18 19 public void read() {//ファイルを読み込み、ArrayListの中に入れる 20 21 try { 22 File file = new File("meibo.txt"); 23 24 if (file.exists()) { 25 if (file.isFile() && file.canRead()) { 26 BufferedReader br = new BufferedReader(new FileReader(file)); 27 28 String str; 29 sortbeanArray.clear(); 30 while ((str = br.readLine()) != null) { 31 String[] arr = str.split(",");//カンマで区切って読み込む 32 SortBean bean = new SortBean(); 33 bean.setID(arr[0]); 34 bean.setName(arr[1]); 35 bean.setBirthDay(arr[2]); 36 bean.setGender(arr[3]); 37 sortbeanArray.add(bean); 38 } 39 br.close(); 40 System.out.println("読み込み完了");//成功 41 } else { 42 System.out.println("読み込み不可");//ファイルはあるが読み込めない 43 } 44 } else { 45 System.out.println("ファイルが見つからない");//ファイルがない 46 } 47 48 } catch (FileNotFoundException e) { 49 System.out.println(e); 50 } catch (IOException e) { 51 System.out.println(e); 52 } 53 } 54 55 public void show() {//ArrayListの中に入れたものをソートした上で一覧表示したい 56 57 System.out.println("ソートせずに一覧表示"); 58 for (int i = 0; i < sortbeanArray.size(); i++) { 59 60 System.out.println(sortbeanArray.get(i).getID() 61 + "," + sortbeanArray.get(i).getName() 62 + "," + sortbeanArray.get(i).getBirthDay() 63 + "," + sortbeanArray.get(i).getGender()); 64 } 65 //ここまで、ソートしないままの一覧表示は可能だがここから先がうまくできない 66 System.out.println("IDでソートし一覧表示"); 67 68 for (int i = 0; i < sortbeanArray.size(); i++) { 69 70 Collections.sort(sortbeanArray, new MemberComparator()); 71 72 System.out.println(sortbeanArray.get(i).getID() 73 + "," + sortbeanArray.get(i).getName() 74 + "," + sortbeanArray.get(i).getBirthDay() 75 + "," + sortbeanArray.get(i).getGender()); 76 } 77 78 } 79} 80//--------------------ここから別ファイルにクラスを分けています------------------------- 81import java.util.Comparator; 82 83public class MemberComparator implements Comparator { 84 85 public int compare(SortBean sb1, SortBean sb2) { 86 87 if (sb1.getID() > sb2.getID()) { 88 89 return -1; 90 } else if (sb1.getID() > sb2.getID()) { 91 return 1; 92 } else { 93 return 0; 94 } 95 } 96 97} 98//----------------------ここから別ファイルにクラスを分けています----------------------- 99public class SortBean { 100 101 private String id; 102 private String name; 103 private String birthday; 104 private String gender; 105 106 public SortBean() { 107 } 108 109 public String getID() { 110 return id; 111 } 112 113 public void setID(String id) { 114 this.id = id; 115 } 116 117 public String getName() { 118 return name; 119 } 120 121 public void setName(String name) { 122 this.name = name; 123 } 124 125 public String getBirthDay() { 126 return birthday; 127 } 128 129 public void setBirthDay(String birthday) { 130 this.birthday = birthday; 131 } 132 133 public String getGender() { 134 return gender; 135 } 136 137 public void setGender(String gender) { 138 this.gender = gender; 139 } 140 141} 142//-------サンプルとしてこの下にテキストファイル"meibo.txt"の内容を入れています(ID、名前、生年月日、性別)--------- 143//これらの内容をソートして表示させたい 144/* 145 14657,田中,1999/11/11,Male 14725,山田,1970/03/12,Female 14833,伊藤,1989/05/01,Female 14949,斎藤,2000/01/12,Male 15050,杉山,2010/05/05,Male 15163,河井,1996/01/30,Female 1525,松田,1989/03/21,Male 153 154*/ 155

試したこと

自分で調べCollectionsとComparatorを使用しソートを行う方法にたどり着き(投稿したコードにそのうちの一つを自分が試しているものに書いています)その方法を使いましたがダメでした。
ほかにも書き方の異なる類似の方法を試しましたが同様にうまくできませんでした。

補足情報(FW/ツールのバージョンなど)

Java17を使用しています。

TN8001👍を押しています

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

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

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

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

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

jimbe

2022/12/28 13:11

コードのマークダウンは、ファイル毎に分けてください。
guest

回答2

0

ベストアンサー

型 MemberComparator は継承された抽象メソッド Comparator.compare(Object, Object) を実装する必要があります

型パラメータTが必要です。
Comparator (Java Platform SE 8 )

if (sb1.getID() > sb2.getID()) {

文字列を不等号で比較することはできません。
数値として比較したいのでしょうから、ID自体を数値にするか比較時に数値するなりしてください。

Java17を使用しています。

せっかくJava17なんでしたら、もうちょっとモダンな書き方でいきましょう^^
歴史的経緯をスルーして使いこなす Java ファイル入出力処理 - Qiita

StreamAPIはちょっと難しいと思ったら、Files.readAllLinesなんかはお手軽です(大きいファイルには向きません)
Files (Java Platform SE 8 )

Java

1import java.io.IOException; 2import java.nio.file.*; 3import java.util.Comparator; 4import java.util.List; 5import java.util.stream.Collectors; 6 7public class SortTest { 8 public static void main(String[] args) throws IOException { 9 var st = new SortTest(); 10 11 var path = Paths.get("meibo.txt"); 12// st.dummy(path); 13 14 st.read(path); 15 st.show(); 16 } 17 18 List<SortBean> sortbeans; 19 20 void read(Path path) { 21 if (!Files.exists(path)) { 22 System.out.println("ファイルが見つからない"); 23 } else if (!Files.isReadable(path)) { 24 System.out.println("読み込み不可"); 25 } else { 26 try (var stream = Files.lines(path)) { 27 sortbeans = stream 28 .map(line -> { 29 var array = line.split(","); 30 var bean = new SortBean(); 31 bean.setID(array[0]); 32 bean.setName(array[1]); 33 bean.setBirthDay(array[2]); 34 bean.setGender(array[3]); 35 return bean; 36 }) 37 .collect(Collectors.toList()); 38 39 // せっかくstream.toList()が追加されたのだから使いたいところだが変更不可 40 // sortで落ちる(UnsupportedOperationException) 41 // [JDK 16 : stream.toList() に見るAPI設計の難しさ - A Memorandum](https://blog1.mammb.com/entry/2021/06/07/000000) 42// .toList(); 43 44 } catch (IOException e) { 45 e.printStackTrace(); 46 } 47 } 48 } 49 50 void show() { 51 System.out.println("ソートせずに一覧表示"); 52 sortbeans.forEach(System.out::println); 53 54 System.out.println("\nIDでソートし一覧表示"); 55 sortbeans.sort(new MemberComparator()); 56 // stream.toList() で変更不可のリストでも、sortedで作り直すことはもちろん可能 57// sortbeans = sortbeans.stream().sorted(new MemberComparator()).toList(); 58 sortbeans.forEach(System.out::println); 59 60 System.out.println("\n名前でソートし一覧表示"); 61 // ↑の省略形 匿名クラス 62 sortbeans.sort(new Comparator<SortBean>() { 63 @Override public int compare(SortBean o1, SortBean o2) { 64 return o1.getName().compareTo(o2.getName()); 65 } 66 }); 67 sortbeans.forEach(System.out::println); 68 69 System.out.println("\n誕生日でソートし一覧表示"); 70 // ↑の省略形 ラムダ式 71 sortbeans.sort((o1, o2) -> o1.getBirthDay().compareTo(o2.getBirthDay())); 72 sortbeans.forEach(System.out::println); 73 74 System.out.println("\n性別でソートし一覧表示"); 75 // ↑の省略形 Comparator.comparing 76 sortbeans.sort(Comparator.comparing(SortBean::getGender)); 77 sortbeans.forEach(System.out::println); 78 } 79 80 void dummy(Path path) throws IOException { 81 var csv = """ 82 57,田中,1999/11/11,Male 83 25,山田,1970/03/12,Female 84 33,伊藤,1989/05/01,Female 85 49,斎藤,2000/01/12,Male 86 50,杉山,2010/05/05,Male 87 63,河井,1996/01/30,Female 88 5,松田,1989/03/21,Male"""; 89 Files.writeString(path, csv); 90 } 91} 92 93class MemberComparator implements Comparator<SortBean> { 94 public int compare(SortBean sb1, SortBean sb2) { 95 return Integer.valueOf(sb1.getID()).compareTo(Integer.valueOf(sb2.getID())); 96 } 97} 98 99class SortBean { 100 private String id; 101 private String name; 102 private String birthday; 103 private String gender; 104 105 public String getID() { return id; } 106 107 public void setID(String id) { this.id = id; } 108 109 public String getName() { return name; } 110 111 public void setName(String name) { this.name = name; } 112 113 public String getBirthDay() { return birthday; } 114 115 public void setBirthDay(String birthday) { this.birthday = birthday; } 116 117 public String getGender() { return gender; } 118 119 public void setGender(String gender) { this.gender = gender; } 120 121 @Override public String toString() { 122 return String.join(",", id, name, birthday, gender); 123 } 124}

投稿2022/12/28 16:51

編集2022/12/28 23:48
TN8001

総合スコア9862

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

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

chahahaan

2022/12/29 07:13

回答ありがとうございます。 丁寧にコードまで書いていただいて本当にありがたいです。 参考URLまで張っていただき恐縮です。 文字列は不等号で比較できない点、言われてみれば確かにそうですが完全に見落としていました。 自分ではまだ知らない記述の仕方がたくさんあるのでひとつずつ調べるなりデバッグで参考にさせていただきます。
TN8001

2022/12/31 01:33

ソートの部分は↓で解決できると思いますがどうでしょうか? > 型パラメータTが必要です。 > 文字列を不等号で比較することはできません。 > 自分ではまだ知らない記述の仕方がたくさんあるのでひとつずつ調べるなりデバッグで参考にさせていただきます。 調べてみて解決できたのなら「解決済」にしてください。 [ヘルプ|質問を解決済みにしたい](https://teratail.com/help#resolve-question) 回答コードについての疑問点や不明点は、お気軽にコメントしてください。 回答コードがモダンすぎるということであれば、Java8以前程度のコード(ggってよく出てくるような)に書き直しても構いませんが...
guest

0

for (int i = 0; i < sortbeanArray.size(); i++) { Collections.sort(sortbeanArray, new MemberComparator());

Collections.sort は、 comparator によって sortBeanArray を並び替えます。
従ってループの中では無く外で行うことです。

Collections.sort(sortbeanArray, new MemberComparator()); for (int i = 0; i < sortbeanArray.size(); i++) {

勉強用なら、 TN8001 さんと違った方向のコードにしてみます。

java

1import java.io.*; 2import java.time.LocalDate; 3import java.time.format.DateTimeFormatter; 4import java.util.*; 5 6public class SortTest { 7 public static void main(String[] args) { 8 try { 9 new SortTest() 10 .readFrom("meibo.txt") //ファイル名は埋め込むよりパラメータで渡す 11 .show("■ ソートせずに一覧表示") 12 .sort((a,b) -> a.id < b.id ? -1 : a.id > b.id ? 1 : 0) //ラムダ式 & 三項演算子 13 .show("■ IDでソートし一覧表示"); 14 } catch(FileNotFoundException e) { 15 System.out.println("ファイルが見つかりません."+e.getMessage()); 16 } catch(IOException e) { 17 System.out.println("ファイルの読み込みで問題が発生しました. "+e.getMessage()); 18 } 19 } 20 21 private List<Person> persons = new ArrayList<>(); 22 23 SortTest readFrom(String filename) throws FileNotFoundException, IOException { //throws で例外時の処理は呼び出し側に任せる 24 persons.clear(); 25 Person.Builder builder = new Person.Builder(); 26 try(BufferedReader reader = new BufferedReader(new FileReader(filename))) { //try-with-resource ( close が自動的 ) 27 for(String line; (line=reader.readLine()) != null; ) { //'readLine' の結果を受ける変数名は 'line' のほうが合ってる感じ. そして変数の有効範囲(スコープ)は狭く 28 String[] tokens = line.split(","); 29 try { 30 if(tokens.length == 4) { 31 persons.add(builder 32 .setId(tokens[0]) 33 .setName(tokens[1]) 34 .setBirthday(tokens[2]) 35 .setGender(tokens[3]) 36 .build()); 37 } else { 38 throw new IllegalStateException("データが4つでは無い. tokens.length="+tokens.length); 39 } 40 } catch(Exception e) { 41 System.out.println("format error. line="+line); 42 e.printStackTrace(); //例外の詳細の表示はコレ 43 } 44 } 45 } 46 System.out.println("読み込み完了"); 47 return this; 48 } 49 50 SortTest sort(Comparator<Person> comparator) { 51 Collections.sort(persons, comparator); 52 return this; 53 } 54 55 SortTest show(String header) { 56 System.out.println(header); 57 for(Person person : persons) System.out.println(""+person); 58 return this; 59 } 60 61 private static class Person { 62 enum Gender { Male, Female } //少ない選択肢なら enum 63 64 //birthday の解析/表示用 65 private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); 66 67 static class Builder { //Person の生成はこのクラスが行う 68 private int id; 69 private String name; 70 private LocalDate birthday; 71 private Gender gender; 72 73 Builder setId(String id) { 74 this.id = Integer.parseInt(id); 75 return this; //自身を返すことで、呼び出し側が '.' で複数のメソッドを繋げて書けるようになる 76 } 77 Builder setName(String name) { 78 if(name == null) throw new NullPointerException(); 79 this.name = name; 80 return this; 81 } 82 Builder setBirthday(String birthday) { 83 this.birthday = LocalDate.parse(birthday, formatter); 84 return this; 85 } 86 Builder setGender(String gender) { 87 this.gender = Gender.valueOf(gender); 88 return this; 89 } 90 Person build() { 91 return new Person(id, name, birthday, gender); 92 } 93 } 94 95 final int id; //final にすると変更出来なくなる 96 final String name; 97 final LocalDate birthday; 98 final Gender gender; 99 100 private Person(int id, String name, LocalDate birthday, Gender gender) { 101 this.id = id; 102 this.name = name; 103 this.birthday = birthday; 104 this.gender = gender; 105 } 106 107 @Override 108 public String toString() { //表示用の文字列を自分で生成する 109 return String.join(",",""+id,name,birthday.format(formatter),""+gender); 110 } 111 } 112}

meibo.txt

plain

157,田中,1999/11/11,Male 225,山田,1970/03/12,Female 333,伊藤,1989/05/01,Female 449,斎藤,2000/01/12,Male 550,杉山,2010/05/05,Male 663,河井,1996/01/30,Female 75,松田,1989/03/21,Male

実行結果

plain

1読み込み完了 2■ ソートせずに一覧表示 357,田中,1999/11/11,Male 425,山田,1970/03/12,Female 533,伊藤,1989/05/01,Female 649,斎藤,2000/01/12,Male 750,杉山,2010/05/05,Male 863,河井,1996/01/30,Female 95,松田,1989/03/21,Male 10■ IDでソートし一覧表示 115,松田,1989/03/21,Male 1225,山田,1970/03/12,Female 1333,伊藤,1989/05/01,Female 1449,斎藤,2000/01/12,Male 1550,杉山,2010/05/05,Male 1657,田中,1999/11/11,Male 1763,河井,1996/01/30,Female

投稿2022/12/28 13:14

編集2023/01/01 17:30
jimbe

総合スコア13209

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

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

chahahaan

2022/12/29 06:52

コメントありがとうございます。 確かにループの中にCollections.sortを置くのはおかしいですね。 参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問