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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

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

Q&A

解決済

4回答

6270閲覧

Javaでのcsv読み取り、合計、上位5位のみ書き出し

kimama8o8

総合スコア11

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

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

0グッド

0クリップ

投稿2017/01/18 08:36

###前提・実現したいこと
1)Javaで下図のようなcsvデータ(学校のテストの結果)を読み取る
氏名,英語,国語,数学
山田,80,70,60,
佐藤,70,50,90,
田中,80,50,70
(生徒数は30名)

2)各教科の合計得点を出し、下図のように上位5名だけの氏名と合計点を別のcsvに出力する(合計点で降順)
加藤,300
後藤,290

###発生している問題・エラーメッセージ
csvから入力、合計計算して出力、まではわかるのですが、上位5名のみ降順で出力、というところで詰まっています。

エラーメッセージ

###該当のソースコード
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class JavaApplication23 {
static List<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>();

public static void main(String[] args) { // TODO code application logic here

try {
FileReader fr = new FileReader(new File("csv.csv"));
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
String[] array = line.split(" ");//配列arrayに文字列格納
calArray(array);

write();
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private static void write() {
try {
FileWriter fw = new FileWriter(new File("out.csv"));
for (ArrayList<String> array : mainList) {
for (String line : array) {

fw.write(line);
fw.write(",");
}
fw.write("\n"+"\n");
}
fw.close();

}catch (IOException e) {
e.printStackTrace();
}
}
private static void calArray(String[] array) {
List<String> list = new ArrayList<String>();//
for (String line : array) {
list.add(line);//読み込んだ文字列(line)をリストに追加
}

if (array[0].equals("氏名")) {
} else {
int sum = 0;
for (int i = 1; i < array.length; i++) {
sum += Integer.parseInt(array[i]);
}
list.add("" + sum); //

//Collections.sort(list);

System.out.println(list);

}
mainList.add((ArrayList<String>) list);
}

###試したこと

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/01/18 14:32

地味なことですが、ソースコードを 括る方が見やすいですよ (```)
guest

回答4

0

ベストアンサー

kimama8o8氏とswordone氏のコードを合わせたものに加筆修正して作った、
csvから入力、合計計算して出力、上位5名のみ降順で出力
までを行うコードが以下です

java

1import java.io.BufferedReader; 2import java.io.BufferedWriter; 3import java.io.File; 4import java.io.FileNotFoundException; 5import java.io.FileReader; 6import java.io.FileWriter; 7import java.io.IOException; 8import java.util.ArrayList; 9import java.util.List; 10import java.util.Collections; 11import java.util.Comparator; 12import java.util.HashMap; 13import java.util.Map; 14import java.util.Map.Entry; 15 16public class JavaApplication23{ 17 static Map<String, Integer> map = new HashMap<>(); 18 19 public static void main(String[] args) { 20 // TODO code application logic here 21 try { 22 FileReader fr = new FileReader(new File("csv.csv")); 23 BufferedReader br = new BufferedReader(fr); 24 String line; 25 while ((line = br.readLine()) != null) { 26 String[] array = line.split(",");// 配列arrayに文字列格納 27 calArray(array); 28 29 } 30 try (BufferedWriter bw = new BufferedWriter(new FileWriter( 31 "out.csv"))) { 32 bw.write("氏名,合計点"); 33 bw.newLine(); 34 } catch (Exception e) { 35 } 36 37 map.entrySet() 38 .stream() 39 .sorted( 40 // Mapのエントリの値(得点)を基準に昇順に並べるコンパレータ 41 // 当方の環境だとEntry周りの型推論がうまくいかず、型宣言をつけないといけないのがつらい 42 Comparator.comparing(Entry<String, Integer>::getValue) 43 .reversed()).limit(5) 44 .forEachOrdered((s) -> write(s)); 45 46 } catch (FileNotFoundException e) { 47 e.printStackTrace(); 48 } catch (IOException e) { 49 e.printStackTrace(); 50 } 51 } 52 53 private static void write(Entry<String, Integer> a) { 54 55 try (BufferedWriter bw = new BufferedWriter(new FileWriter("out.csv", 56 true))) { 57 String b = a.getKey(); 58 int c = a.getValue(); 59 60 bw.write(b + "," + c); 61 bw.newLine(); 62 } catch (Exception e) { 63 } 64 65 System.out.println(a); 66 67 } 68 69 private static void calArray(String[] array) { 70 71 if (array[0].equals("氏名")) { 72 } else { 73 int sum = 0; 74 for (int i = 1; i < 4; i++) { 75 String aw = array[i].trim(); 76 sum += Integer.parseInt(aw); 77 } 78 map.put(array[0], sum); 79 } 80 81 } 82} 83

投稿2017/01/18 18:00

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kimama8o8

2017/01/20 05:16

ご回答ありがとうございます。
guest

0

「名前」と「合計点」だけでいいなら、Mapを使うという手もあります。
入出力はわからないので、動きのシミュレート的に書いてみました。

java

1import java.util.Comparator; 2import java.util.HashMap; 3import java.util.Map; 4import java.util.Map.Entry; 5 6public class Q62481 { 7 public static void main(String[] args) { 8 Map<String, Integer> map = new HashMap<>(); 9 String[] names = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}; 10 int[] scores = {300, 290, 180, 230, 120, 140, 150, 110, 40, 90}; 11 for(int i = 0; i < names.length; i++) { 12 map.put(names[i], scores[i]); 13 } 14 map.entrySet().stream().sorted( 15 //Mapのエントリの値(得点)を基準に昇順に並べるコンパレータ 16 //当方の環境だとEntry周りの型推論がうまくいかず、型宣言をつけないといけないのがつらい 17 Comparator.comparing(Entry<String, Integer>::getValue).reversed() 18 ).limit(5).forEachOrdered(System.out::println); 19 } 20} 21

投稿2017/01/18 16:20

swordone

総合スコア20649

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

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

kimama8o8

2017/01/20 05:16

ご回答ありがとうございます。
guest

0

ソースをお見受けしたところ、Collectionsのsortで詰まっているようですので、
そこらへんの実装を書いてみます。
#なお、机上デバッグのみなので、バグがあったらごめんなさい。

まず、出力に欲しい要素は、「名前」と「合計点数」です。
Stringのままだと扱いにくいので、古典java的ですが、
nameとpointを返すpointsオブジェクトを作成します。

java

1//Points.java 2public class Points { 3 private String name; 4 private int points; 5 6 /** 7 * @return name 8 */ 9 public String getName() { 10 return name; 11 } 12 /** 13 * @param name セットする name 14 */ 15 public void setName(String name) { 16 this.name = name; 17 } 18 /** 19 * @return points 20 */ 21 public int getPoints() { 22 return points; 23 } 24 /** 25 * @param points セットする points 26 */ 27 public void setPoints(int points) { 28 this.points = points; 29 } 30}

また、これに合わせ、結果を入れるListは、作成したPointsオブジェクトを格納するよう、

java

1List<Points> pointList = new ArrayList<Points>();//

とし、add部分は以下のように、オブジェクトに値を詰め込みます。

java

1Points myPoints = new Points(); 2myPoints.setName(array[0]); 3myPoints.setPoints(sum); 4pointList.add(myPoints);

これでpointListには「名前」「合計点」が関連付けられた状態で入っています。
このpointListを任意の条件でソートするために、コンパレータを実装します。

java

1//MyComparator.java 2import java.util.Comparator; 3 4public class MyComparator implements Comparator<Points> { 5 6 public int compare(Points a, Points b) { 7 if (a.getPoints() < b.getPoints()) { 8 return 1; 9 } else if (a.getPoints() = b.getPoints()) { 10 return 0; 11 } else { 12 return -1; 13 } 14 } 15}

最後に、コンパレータを用いて、コレクションのソートを行います。

//Collections.sort(list);

の、部分を、

java

1 Collections.sort(pointList, new MyComparator());

これで、実行後のpointListは、ソートされているはずです。

投稿2017/01/18 11:00

akio221

総合スコア716

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

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

kimama8o8

2017/01/20 05:16

ご回答ありがとうございます。
guest

0

クラスを作ったりなんかすると便利になるかと思います。

たとえば、

java

1// ScoreInfo.java 2class ScoreInfo { 3 public String name; // 氏名 4 public int score; // 合算された成績 5 6 public ScoreInfo(String name, int score) { 7 this.name = name; 8 this.score = score; 9 } 10}

といった形です。

その後、Javaで自作クラスをソートする3通りの方法【Java8】 - 俺とプログラミングなどを参考に、次のようにソートすることが可能になります。

java

1ArrayList<ScoreInfo> list = new ArrayList<ScoreInfo>(); 2// list.add(new ScoreInfo(String 氏名, int 成績);をデータ分だけ行います。 3list.sort((info1, info2) -> info2.score - info1.score); // 結果が正の数だと前に移動され、負の数だと後ろに移動します。

その後、先頭の要素を取り出していくと完成します。

参考サイト

投稿2017/01/18 10:51

taka.impact

総合スコア32

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

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

kimama8o8

2017/01/20 05:15

ご回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問