Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

ファイル操作

お世話になっております。
質問させください。
ファイル操作について質問なのですが、
ファイルを読み込んできて、すでに読み込んできた値と
同じ値がいたらエラーを出すロジックを作っています。
エラーが見つかった箇所をn行目として出力したいのですが
かなり苦戦しているので、アドバイスをいただけたらと思います。
ソースはこんな感じです。
よろしくお願いいたします。
InputStreamReader isr = new InputStreamReader(new FileInputStream(Fname));
BufferedReader fr = new BufferedReader(isr);
//設定ファイルエラーチェック
String spl = "";
int count = 0;
while ((spl = fr.readLine()) != null) {
String[] array = spl.split(",");                    
if(array.length !=2){System.out.println("CSVが2項目ではありません");}
list1.add(array);
}

//2次元に変換 
String[][] array = (String[][]) list1.toArray(new String[list1.size()][]);

//同一のデータがいたらエラー
String n ="";
for(int b = 0; b < array.length; b++) {
if(!set.add(array[b][1])) {
n = array.length;
System.out.println(n+"行目に同一データが存在します。");
}
}

3

回答

4526

閲覧

3件の回答

評価

0

ループカウンタにbという名前を使うのは、ぱっと見分かりづらいのでやめておいた方が良いと思います。
ループカウンタは、FORTRAN時代からの慣習でi, j, k…を使います。
それから、ループの最大値にarray.lengthを使うと、数が多い場合にパフォーマンスが悪いので、以下のようにしましょう。

for (int i = 0, n = array.length; i < n; i++) {

それはともかく…。

setという変数は、どこから出てきたんでしょうか。
どう苦戦しているのか、分かりません。
また、String nにarray.lengthを代入しようとしているのも不明です。
とりあえず、出力すべきはn行目ではなく(b+1)行目だと思いますが。

同一値のチェックはMapを使うと楽にできます。
また、データの幅が予想でき、それが小さい値であるなら、単純に配列を埋めていっても良いでしょう。
このほうがパフォーマンス的には優れています。

評価

0

mioさん返信ありがとうございます。
SETという変数は Set set = new HashSet();上で宣言していました。
同一値のチェックはsetのaddメソッドで同じ値がいたらはじくようにしています。
mapも使ってためしてみます。ありがとうございます。
array.lengthをnに代入したのは、if文に入ったときのarrayのlengthで同一のデータ
がいた行数目をとれる思ったのですが、実行してみると結果が違うので苦戦しております。
アドバイスよろしくお願いいたします。

評価

0

>array.lengthをnに代入したのは、if文に入ったときのarrayのlengthで同一のデータ
>がいた行数目をとれる思ったのですが、実行してみると結果が違うので苦戦しております。
array.lengthは「//2次元に変換」の時点で、確定しています。全体の行数のはずです。
行数はbでカウントしているのではないですか?

「不明」と言ったのは、Stringで宣言した変数にintを代入している、ということです。
コンパイルエラーになりませんか。

しかし、同一値のチェックはファイルの読み込みループでできるはずです。
この場合、list1.size()が現在の行数になるはずです。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。