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

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

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

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

ArrayList

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

8825閲覧

Java リスト内の配列の比較方法

javabigineer

総合スコア87

Java

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

ArrayList

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2016/02/25 00:48

編集2016/02/25 01:00

Java言語で、2つのリスト内の配列を比較して、一致するものとしないものを判定したいです。
良い方法があれば教えてください。

【やりたいこと】
List<String[]> list1 = new ArrayList<String[]>;
List<String[]> list2 = new ArrayList<String[]>;

list1内の中身
1行目 ヘッダー(配列)
2行目以降 ID,値(配列)

list2内の中身
1行目 ヘッダー(配列)
2行目以降 値(配列)
list1内の配列とlist2内の配列が一致すれば、その一致した値のIDを取得する
一致したものは更新用リストへ、しなかったものは新規追加用リストへ

下記のソースだと、list2の1行目(ヘッダー部分)を毎回確認して、新規リストに追加してしまう。

【現状のソース】
//台帳情報の1行ずつ照合する
for(String[] master : list1){
//対象リストを1行ずつ確認する
for(String[] input: list2){

//取込用配列から返却用(ID追加版)配列を取得 String[] result = new String[input.length+1]; System.arraycopy(input, 0,result , 1, input.length); //1行目の場合 if(i == 0 && j==0 ){ result[0] = "ID"; resultList.add(result); //更新用ファイル情報リストに追加 UpdList.add(result); //新規追加用ファイル情報リストに追加 NewList.add(result); j++; break; } //台帳内の案件番号とRedmine取込対象リストの案件番号が等しいものがあった場合 if(master[3].equals(result[1])){ //台帳のIDを対象リストのIDを代入する result[0] = master[0]; resultList.add(result); //更新用ファイル情報リストに追加 UpdList.add(result); }else{ //対象リストのIDに""(空文字)を代入する result[0] = ""; resultList.add(result); //新規追加用ファイル情報リストに追加 NewList.add(result); } j++; } i++; } //更新用ファイル情報リストをセットする setUpdList(UpdList); //新規追加用ファイル情報リストをセットする setNewList(NewList);

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

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

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

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

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

t_obara

2016/02/25 00:53

良い方法とは、どのような観点での「良い」なのでしょう?ご提示のコードでは想定通りの動作をしないので、それを改善したい?もっと早くしたい?処理負荷を減らしたい?などなど
javabigineer

2016/02/25 00:57

掲示したコードでは想定の動作をしないため、改善したい、欲を言えば処理不可を減らす比較方法をご存知の方がいれば教えていただきたい という意味です。
swordone

2016/02/25 01:06

データ構造がよく分かりません。どこをどう比較したいかもわかりにくいです。また変数をiとjの2つも用意する必要がありますか?
guest

回答3

0

ベストアンサー

eclipse 前提で、無くても多少の労力です。hashcode だけはかなりの労力必要ですけど。

java

1 2public class Data { 3 private String id, name, address, zipcode; 4 // コンストラクタ、getter/setter 省略、hashcode, toString を実装、 5 // 手書きの場合は、hashcode の書き方を検索してください。 6}

list1 と list2 は取得元が違うだけで内容は、同一構成の csv 形式のデータファイルと仮定します。
csv は、先頭行にヘッダがあり、以降にデータが続く、カンマ区切りである。

配列操作だけでやると、今回のようのわけがわからなくなるので、csv の1行のデータを格納可能なクラスを用意します。上記の通りです。csv 内容は知らないので変数名などは調整してください。基本文字列型で宣言しますが、数値として比較したり計算する用途があれば、数値型で宣言しておくと良いです。
csv のヘッダ名称が日本語全角文字の場合でも、一応幾つかの制限はあるが、java では日本語の変数名が使えますが、ローマ字に意訳して、半角英数で宣言した方が無難です。ヘッダ名とクラス内の変数名は同じにします。

次に、ハッシュマップを用意します。
Map<String, Data> list1, list2;
マップのキーは id, 値は、 id の Data クラスです。
初期の読み込み順序が重要ならば、map の初期化は、LinkedHashMap を使います。初期読込順序が保証されます。
あとは、
for (Entry e : list2.entrySet()) {
String key = e.getKey();
if (list1.containsKey(key)) {
// キーが一致する行がある。
if (list1.get(key).equals(e.getValue()) {
// キーと全てのデータ内容が等しいときの処理
} else {
// キーは同じだが内容が微妙に異なるデータの処理
}
} else {
// list2 にだけ含まれる場合の処理
}
}
で判断すれば、list2 にのみ存在するデータと、list1とlist2 で差分があるデータが取得できます。
最後に、list1 にしか無いデータ、これが新規挿入するデータになりますが、これの判定は、list1
のループで list2 の検索 ng データを判定すればいけますね。
このとき、list1 と list2 両方に存在するデータは、list1 から除去します。結果、list1 には、
新規行データのみになります。

以上です。手間はこっちの方が遥かに手間ですが、配列操作でゴニョゴニョするよりは java っぽいです。
sql でいう full outer join と同じ事を java でやる感じですね。

投稿2016/02/25 01:43

ipadcaron

総合スコア1693

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

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

0

うまく動作させたいという場合

片方のリスト(あまり変動がないものをソートしておくと尚良いかも、あるいはハッシュ・連想配列で保存)
もう片方のリストを一つずつ取り出し、上記のリストに含まれるか確認する、それをなくなるまで繰り返す
containsメソッド
連想配列の場合値が存在しないもの

という形にするともう少しみやすくスッキリするかと思います。

投稿2016/02/25 01:21

t_obara

総合スコア5488

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

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

0

下記のソースだと、list2の1行目(ヘッダー部分)を毎回確認して、新規リストに追加してしまう。


■もし一行目は必ずヘッダだとわかっているなら、
list1 と list2 の行番号なりをカウント取って、
(idx1 = 0 || idx2 == 0) だったらスキップ、とかで良いのではないでしょうか。

※i, j がそれぞれ list1, list2 の添え字的なものかと思いましたが、違うっぽいですかね・・・?
j の 0 クリアがないし・・・


■あるいは、IDは必ず数値であるとか、何かそういう規則性がある項目があるなら、
その項目をチェックして新規リストに追加するかどうか決める、とかでも良いかもしれません。

投稿2016/02/25 01:21

編集2016/02/25 01:25
sk_3122

総合スコア1126

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問