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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

5回答

9498閲覧

Javaでarraylistを使って任意順のソートをしたい

Erebea

総合スコア13

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

2クリップ

投稿2016/11/11 02:09

###前提・実現したいこと
CSVを読んで中身を変換、ソートして標準出力をしたい。
CSVの中身は

1
A100,yyyyMMdd,名前
S234,yyyyMMdd,名前


となっていて、頭の数字が1なら降順、0なら昇順にする。
データ欠損、存在しない日、アンパサンドのデータなどのエラーは表示しない。

ソートはIDの1文字目でAEDGSRの順で並べたい。それ以外はエラーになる。

###発生している問題・エラーメッセージ
任意順のソートができない

###該当のソースコード

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import dateconversion.Mysort;

public class Reader {
public static void main(String args[]) {
// 1行を格納する箱作成
List<Mysort> tmpList = new ArrayList<Mysort>();
File file = new File(args[0]); // CSVデータファイル

if (file.isFile()) { try (BufferedReader br = Files.newBufferedReader(Paths.get(args[0]), Charset.forName("MS932"))) { // ファイルオープン String line; String retention = null; int sub1; String sub2 = null, sub3 = null, addsub = null; while ((line = br.readLine()) != null) { Mysort M = new Mysort(); if (line.length() == 1) { //始めの1行用 retention = line; } else { try { String[] cols = line.split(","); if (cols.length == 3) { M.setSub1(cols[0]); M.setSub2(cols[1]); M.setSub3(cols[2]); sub1 = M.getChange1(); sub2 = M.getChange2(); sub3 = M.getChange3(); if (sub1 != 9 && sub2 != null && sub3 != null && cols[0].length() == 4) { sub3 = cols[2]; //文字列結合 addsub = cols[0] + "," + sub2 + "," + sub3; // 文字列を格納

// M.add(sub1);

} } } catch (NumberFormatException e) { } } } if (retention.equals("1")) { // 降順になる } else if (retention.equals("0")) { // 昇順になる } Collections.sort(tmpList, new Comparator<Mysort>() public int compare(Mysort mysort1, Mysort mysort2) { int temp = 0; if (mysort1.getChange1() > mysort2.getChange1()) temp = -1; if (mysort1.getChange1() < mysort2.getChange1()) temp = 1; if (temp == 0) { temp = mysort1.getChange2().compareTo(mysort2.getChange2()); return temp; } for (int i = 0; i < tmpList.size(); i++) { System.out.println(tmpList.get(i)); } } catch (IOException e) { e.printStackTrace(); } } else { System.out.println("ファイル指定が間違っています"); System.exit(-1); }

}
_________________________
package dateconversion;

public class Mysort {

private String sub1; private String sub2; private String sub3; public String getSub1() { return sub1; } public void setSub1(String sub1) { this.sub1 = sub1; } public String getSub2() { return sub2; } public void setSub2(String sub2) { this.sub2 = sub2; } public String getSub3() { return sub3; } public void setSub3(String sub3) { this.sub3 = sub3; } @Override public String toString() { return sub1 + ", " + sub2 + ", " + sub3; } public int getChange1() { int change1; switch (sub1.substring(0, 1)) { case "A": change1 = 1; break; case "E": change1 = 2; break; case "D": change1 = 3; break; case "G": change1 = 4; break; case "S": change1 = 5; break; case "R": change1 = 6; break; default: change1 = 9; } return change1; } public String getChange2() { return Converter.conversion(sub2); } public String getChange3() { return Nullchecker.nullchecker(sub3); }

}
__________________________
package dateconversion;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Mfnumconverter {

public static String mfnumconvertion(String mfnum) { String sub2 = null; boolean bo = Nullchecker.isNotEmpty(mfnum); if (bo == true) { String num1 = mfnum.substring(0, 1); String num2 = mfnum; boolean num3 = Mfnumconverter.isNumberStr(mfnum.substring(1)); if (num1.equals("A") || num1.equals("E") || num1.equals("D") || num1.equals("G") || num1.equals("S") || num1.equals("R")) { if (num2.length() == 4 && num3 == true) { sub2 = num2; } } return sub2; } return sub2; } public static boolean isNumberStr(String num3) { Pattern p = Pattern.compile("^[0-9]+$"); Matcher m = p.matcher(num3); return m.find(); }

}

###試したこと

IDの1文字目を切り取って数字を割り振った

###補足情報(言語/FW/ツール等のバージョンなど)
win10 64bit
Java 8
eclipse

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

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

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

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

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

swordone

2016/11/11 02:38

マークダウン記法を使ってください。
swordone

2016/11/11 03:00 編集

当方のEclipseに入れてみましたが、コンパイルエラーが多すぎて読めたものじゃありません。最低限コンパイルが通る形にして下さい。あとConverterとかNullCheckerとか謎のクラスが登場していますが、これは何でしょう?
Erebea

2016/11/11 06:07

要点を抑えていない質問、わけの分からない状態のプログラムから意図を汲み取って返信してくだりありがとうございます。一応他にもクラスが有り、ConverterはyyyyMMddをyyyyMMdd(E)に変換するクラス、NullChecerはCVSデータの欠損を阻止するためのクラスでした。IDの頭文字の英語を数字に変換し、その数字をデータの最初に来る0or1で昇順、降順の判断、をするというところが試行錯誤するうちにわからなくなってしまっていました。 これらを参考にもう一度作り直してみたいと思います。ありがとうございました。
guest

回答5

0

ソートはよく使う操作なのでjava(に限らず大抵の言語で)標準ライブラリーに順序付きの列を表現するいくつかのデータ型(配列、List、Stream, ... etc.)に対してソートするメソッドが提供されています。

ソートするには任意の2つの要素の順序を決めることが必要です。アプリケーションによってどういう順序にしたいかは様々なので、ソートを行うライブラリーは「2つのデータの大小比較を行った結果を負、0、正のいずらかの整数で返すComparatorを指定させる」ことで任意の順番のソートを行えるように設計されています。つまり「ソートを実現する」ことは「Comparatorを定義する」問題に帰着します。本件についてちょっと工夫が必要なのは以下の点です。

AEDGSRの順番に並べる

このような「そのままでは大小比較が単純にできないもの」を大小比較するための基本的な考え方は、与えられた'A'なり'E'なりといったデータを、順番を表す数値0, 1, ...へ写像(変換)することです。ありえるデータの種類がごく少数ならswitch文で変換してもよいでしょうし、多いならHashMapなどを使って変換を高速化するなどの方式をとることもあるでしょう。また1文字の場合ならString#indexOfを使うという手もあります。いずれにせよあり得るデータの種類に対して(漏れなく)一意な数値に変換する方法が考えられればよいのです。

ちなみに昇順、降順は要するに順序が逆なだけですからどちらかを表すComparatorCを定義してやりさえすれば、それを用いて-Cを返すもう一つのComparatorを定義するだけで昇順、降順の両方のソートが可能です。

投稿2016/11/11 04:58

KSwordOfHaste

総合スコア18392

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

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

swordone

2016/11/17 07:59

ちなみにJava8では、昇順、降順いずれかのComparatorを作れば、そのComparatorに対してreversed()を呼び出すだけで逆順のComparatorを作ることが可能です。
KSwordOfHaste

2016/11/20 14:17

そういえばみたことありましたw;使わないとすぐ忘れちゃいますね。
guest

0

ベストアンサー

ややこしい仕様や設計はメイン処理に書かず、オブジェクトにまとめるようにします。
具体的には、データの妥当性の判定(データ欠落、日にち間違いなど)はコンストラクタで、
並び順はComparableを付けてcompateToで判定させます。
(以下コードは動作未検証)
###Readerクラス

java

1import java.io.BufferedReader; 2import java.io.File; 3import java.io.IOException; 4import java.nio.charset.Charset; 5import java.nio.file.Files; 6import java.nio.file.Paths; 7import java.util.ArrayList; 8import java.util.Collections; 9import java.util.List; 10 11public class Reader { 12 13 public static void main(String args[]) { 14 // 1行を格納する箱作成 15 List<Mysort> tmpList = new ArrayList<Mysort>(); 16 File file = new File(args[0]); // CSVデータファイル 17 18 if (!file.isFile()) { 19 System.out.println("ファイル指定が間違っています"); 20 System.exit(-1); 21 } 22 try (BufferedReader br = Files.newBufferedReader(Paths.get(args[0]), Charset.forName("MS932"))) { 23 // ファイルオープン 24 String line; 25 final boolean acsend = br.readLine().equals("0"); 26 while ((line = br.readLine()) != null) { 27 try { 28 Mysort M = new Mysort(line); 29 tmpList.add(M); 30 } catch (IllegalArgumentException e) { 31 e.printStackTrace(); 32 } 33 34 } 35 36 if (acsend) { 37 Collections.sort(tmpList); 38 } else { 39 Collections.sort(tmpList, Collections.reverseOrder()); 40 } 41 42 for (int i = 0; i < tmpList.size(); i++) { 43 System.out.println(tmpList.get(i)); 44 } 45 } catch (IOException e) { 46 e.printStackTrace(); 47 } 48 } 49 50}

###Mysortクラス

java

1import java.time.LocalDate; 2import java.time.format.DateTimeFormatter; 3import java.time.format.DateTimeParseException; 4import java.util.Arrays; 5 6public class Mysort implements Comparable<Mysort> { 7 private static final String INDEX = "AEDGSR"; 8 private String id; 9 private LocalDate localDate; 10 private String name; 11 12 public Mysort(String line) throws IllegalArgumentException { 13 String[] ids = line.split(","); 14 if (ids.length != 3) { 15 throw new IllegalArgumentException("Length of data is invalid: " + line); 16 } 17 if (Arrays.asList(ids).contains("")) { 18 throw new IllegalArgumentException("It has blank data: " + line); 19 } 20 if (INDEX.indexOf(ids[0].charAt(0)) == -1) { 21 throw new IllegalArgumentException("Invalid index: " + line); 22 } 23 try { 24 id = ids[0]; 25 localDate = LocalDate.parse(ids[1], DateTimeFormatter.BASIC_ISO_DATE); 26 name = ids[2]; 27 } catch (DateTimeParseException e) { 28 throw new IllegalArgumentException("Invalid date: " + line, e); 29 } 30 } 31 // やたら長く書いていた文字と番号の対応は、String#indexOf(char)や配列を使うと楽 32 public int getIndex() { 33 return INDEX.indexOf(id.charAt(0)); 34 } 35 36 public String getName() { 37 return name; 38 } 39 40 @Override 41 public String toString() { 42 return name + ", " + localDate + ", " + name; 43 } 44 45 @Override 46 public int compareTo(Mysort o) { 47 int temp = this.getIndex() - o.getIndex(); 48 if (temp == 0) { 49 temp = this.localDate.compareTo(o.localDate); 50 } 51 return temp; 52 } 53} 54

投稿2016/11/11 04:30

編集2016/11/11 05:02
swordone

総合スコア20649

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

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

0

Comparatorの定義の問題なのですが、以下のようにすればよいと思います。
(アイデアを見やすくするため、質問者さんのソースとは違います。)

サンプル

package test54773; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Reader { public static void main(String args[]) { int num = 0; // 1なら降順、0なら昇順にする List<String> list = new ArrayList<>(); // CSVのデータ各行 File file = new File("resource/test54773.txt"); try (BufferedReader br = new BufferedReader(new FileReader(file))) { // 1行目を読み取る。 num = Integer.parseInt(br.readLine()); // 2行目からはデータ String line = null; while ((line = br.readLine()) != null) { list.add(line); } } catch (FileNotFoundException e) { System.out.println("ファイルが存在しません。"); } catch (IOException e) { System.out.println("エラーが発生しました。"); } // 並び替え final int caseOfSort = num; Collections.sort(list, new Comparator<String>() { @Override public int compare(String s1, String s2) { char c1 = s1.charAt(0); char c2 = s2.charAt(0); int value = value(c1) - value(c2); return value != 0 ? value : s1.compareTo(s2); } private int value(char c) { int value = 9; switch (c) { case 'A': value = 1; break; case 'E': value = 2; break; case 'D': value = 3; break; case 'G': value = 4; break; case 'S': value = 5; break; case 'R': value = 6; break; } return caseOfSort == 0 ? value : -value; } }); // 出力 for (String s : list) { System.out.println(s); } } }

出力

S234,yyyyMMdd,名前 E101,yyyyMMdd,名前 A100,yyyyMMdd,名前 A102,yyyyMMdd,名前 A103,yyyyMMdd,名前

test54773.txtの内容

1 A100,yyyyMMdd,名前 S234,yyyyMMdd,名前 E101,yyyyMMdd,名前 A103,yyyyMMdd,名前 A102,yyyyMMdd,名前

投稿2016/11/11 03:41

編集2016/11/11 04:10
java-beginner

総合スコア452

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

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

0

以下のコードでできると思います

java

1import java.io.*; 2import java.util.*; 3import java.util.regex.Pattern; 4 import java.util.regex.Matcher; 5import java.text.DateFormat; 6import java.text.SimpleDateFormat; 7import java.text.ParseException; 8 9class QL{ 10 11 12public static void main(String[] args){ 13 14try(BufferedReader br=new BufferedReader(new FileReader("C1.csv"))){ 15int count=0; 16String data=null; 17int flag=0; 18 19ArrayList<Data> st=new ArrayList<>(); 20 21while((data=br.readLine())!=null){ 22 23Data d=new Data(); 24d.data=data; 25 26 27 28if(count==0){ 29 30try{ 31int c=Integer.parseInt(data); 32 33if(c==1)flag=1; 34if(c==0)flag=0; 35count++; 36continue; 37}catch(Exception o){} 38} 39 40String r[]=data.split(","); 41 42if(r.length!=3){ 43 44count++; 45continue; 46} 47 48DateFormat format=new SimpleDateFormat("yyyyMMdd"); 49format.setLenient(false); 50 51try{ 52java.util.Date date = format.parse(r[1]); 53 54}catch(Exception m){ 55count++; 56continue; 57} 58 59 60 61 62String regex = "[A|E|D|G|S|R][0-9]"; 63Pattern p = Pattern.compile(regex); 64Matcher m = p.matcher(data); 65if (m.find() ) { 66 67//System.out.println ( m.group().replaceAll("[0-9]","") + " "); 68try{ 69char c=m.group().replaceAll("[0-9]","").charAt(0); 70 71int c2=(int)c; 72 73d.id=c2; 74}catch(Exception p2){} 75 76}else{ 77count++; 78continue; 79} 80 81st.add(d); 82count++; 83} 84 85//書き出し 86 87if(flag==0){ 88Collections.sort(st,new Sorts()); 89} 90if(flag==1){ 91Collections.sort(st,new Sorts2()); 92} 93 94for(Data as:st){ 95 96System.out.println(as.data); 97} 98 99}catch(Exception r){} 100 101 102} 103 104 105} 106 107 108 109class Data{ 110 111Integer id=0; 112 113String data=""; 114 115 116} 117 118 119class Sorts implements Comparator<Data>{ 120 121public int compare(Data d1,Data d2){ 122 123return d1.id.compareTo(d2.id); 124 125} 126 127 128} 129 130 131class Sorts2 implements Comparator<Data>{ 132 133public int compare(Data d1,Data d2){ 134 135return d2.id.compareTo(d1.id); 136 137} 138 139 140}

投稿2016/11/11 03:30

編集2016/11/11 03:40
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

質問者さんの目標が今ひとつ理解できないのですが、

文字列型のArrayListを6個作り、先頭の一文字を判定して、6個のうちどれかに1行の文字列を格納する
全データを処理したら、ファイルの先頭の1/0に従って、望む順に出力する

じゃ、ダメなのでしょうか?

投稿2016/11/11 03:07

nob.

総合スコア711

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問