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

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

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

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

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Eclipse

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

配列

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

Q&A

解決済

1回答

1826閲覧

2つのListを比較し異なる要素をもつものだけを条件分岐させたい

THE_GUTS

総合スコア2

Java

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

String

Stringは、ゼロ以上の文字から連続してできた文字の集合を扱うデータ型です。基本的にテキストを表すために使われます。

Eclipse

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

配列

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

0グッド

1クリップ

投稿2021/10/28 21:49

編集2021/10/31 06:22

前提・実現したいこと

Java初心者です。
二つのList<Map<String,Object>>型で作成したListの要素を比較し
異なる要素があるListのみ(下記ソースコードでいうと[1]のみ)を条件分岐させたいです。
ご教示いただければと思います。

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

① 下記の書き方だと ListA[0]とListB[0] ListA[0]とListB[1] ListA[1]とListB[0] ListA[1]とListB[1] の比較をしているようです。 【やりたいこと】 ListA[0]とListB[0] ListA[1]とListB[1] のみ比較して、条件分岐させたいと考えています 格納が多くなるにつれて ListA[3]とListB[3] ListA[4]とListB[4] .... ② ListAをListBとしてコピーしたのですが、 ListAの要素を書き換えるとListBも更新されます。(意図しない実装になっています。) サイト等を見てディープコピーとしてコーディングしているのですが、なぜこうなるのかが分かりません。

該当のソースコード【OLD】

java

1List<Map<String,Object>> ListA new ArrayList<Map<String,Object>>(); 2 3Map<String,Object> mapA = new HashMap<String,Object>(); 4Map<String,Object> mapB = new HashMap<String,Object>(); 5 6// ListAに格納処理 7mapA.put ("性別", "男性"); 8mapA.put ("名前", "山田"); 9mapA.put ("年齢", "20"); 10ListA.add(mapA) 11 12mapB.put ("性別", "女性"); 13mapB.put ("名前", "田中"); 14mapB.put ("年齢", "25"); 15ListA.add(mapB) 16 17// ListBに格納処理(ListAの[1]の年齢だけ異なる) 18List<Map<String,Object>> ListB new ArrayList<Map<String,Object>>(); 19mapA.put ("性別", "男性"); 20mapA.put ("名前", "山田"); 21mapA.put ("年齢", "20"); 22ListB.add(mapA) 23 24mapB.put ("性別", "女性"); 25mapB.put ("名前", "田中"); 26mapB.put ("年齢", "50"); 27ListB.add(mapB) 28 29//Listを比較し、異なるものを条件分岐させる 30for(Map<String, Object> map : ListA) { 31 for(Map<String, Object> map2 : ListB) { 32 if(!(map.equals(map2))) { 33 34//DB更新処理 35   } 36 } 37 }

修正後のソースコード

java

1List<Map<String, Object>> ListA = new ArrayList<Map<String, Object>>(); 2 3Map<String, Object> mapA = new HashMap<String, Object>(); 4Map<String, Object> mapB = new HashMap<String, Object>(); 5 6// ListAに格納処理 7mapA.put("性別", "男性"); 8mapA.put("名前", "山田"); 9mapA.put("年齢", "20"); 10ListA.add(mapA); 11 12mapB.put("性別", "女性"); 13mapB.put("名前", "田中"); 14mapB.put("年齢", "25"); 15ListA.add(mapB); 16 17// リストAを複製 18List<Map<String, Object>> ListB = new ArrayList<Map<String, Object>>(ListA); 19 20//間違った実装によりコメントアウト 21//mapB.put("性別", "女性"); 22//mapB.put("名前", "田中"); 23mapB.put("年齢", "50"); 24//ListA.add(mapB); 25 26 27// ListAとListBを比較し、異なるものを条件分岐させる 28for (Map<String, Object> map1 : ListA) { 29 for (Map<String, Object> map2 : ListB) { 30 if (!(map1.equals(map2))) { 31 32 // DB更新処理 33 } 34 } 35}

試したこと

java

1Map<String, Object> mapCompare = new HashMap<String, Object>(); 2Map<String, Object> motoMap = new HashMap<String, Object>(); 3 4for (int j = 0; j < ListA.size(); j++) { 5 motoMap.putAll(ListA.get(j)); 6 for (int i = 0; i < ListB.size(); i++) { 7 mapCompare.putAll(ListB.get(i)); 8 if (!(motoMap.equals(mapCompare))) { 9 } 10 } 11}

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

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

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

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

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

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

dodox86

2021/10/28 22:58

> 下記の書き方だと ... > の比較をしているようです。 「しているよう」、と言いますか、それは質問さん自身が2重ループでまさにそのように比較しているからなのですが。LstA[0]とListB[0], ListA[1]とListB[1] のように比較したいのであれば、ループはひとつで良いはずです。 また、要素であるmap同士を比較する方法、if(!(map.equals(map2))) の部分はそれとは分けて考えましょう。 > 格納する要素が多くなるほど処理が多くなりそうなため採用しませんでいた。 多くなっても要望が実現できるなら、まず自分なりにそれをやってみるべきです。 [質問するときのヒント] https://teratail.com/help/question-tips
BluOxy

2021/10/29 04:16

該当ソースコードの map.equals(map2) は false になる想定でしょうか。現状だと true になると思いますが、認識は合っていますか。 例えば、1回目のループにおける map, map2 は両者とも mapA を参照しています。同じ参照同士の比較は true になると思います。 ソースコードを見るとあたかも ListA には3つの要素が入った mapA, mapB を、ListB には6つの要素が入った mapA, mapB を add したいように見えたので、もしそうだとしたら意図していない実装になっているのではないかと推測しています。
Crimson_Tide

2021/10/29 10:06

;がなかったりでこのソースコードではコンパイルが通りません 大前提としてコンパイルが通るようにまずはしてください
jimbe

2021/10/29 10:07

勘違いされている点が幾つかあるようですが、まず for ループをする直前で、ListA/B 両方の中のデータを表示してみて、思ったようになっているか確認しては如何でしょうか。
THE_GUTS

2021/10/31 04:50

回答遅くなり申し訳ございません。 また、アドバイスありがとうございます。 Crimson_Tide様がおっしゃるように まずはコンパイルが通るように修正しました。 BluOxy様、jimbe様がおっしゃるように 修正前のコードを動かして確認すると意図しない実装になっていました。 そこで私が実装してかったのは、 更新前のListAをコピーしそれを保持した状態で(ListBとして) ListAの要素を更新したあとに、ListAとListBを比較して条件分岐させる。です。 ただ、それを実装したときにまた新たに問題が発生しました。 【発生している問題・エラーメッセージの②】 dodox86様がおっしゃるように 試してみたことを書きました。 ただ、結局結果は同じでした。 >LstA[0]とListB[0], ListA[1]とListB[1] のように比較したいのであれば、ループはひとつで良いはずです。また、要素であるmap同士を比較する方法、if(!(map.equals(map2))) の部分はそれとは分けて考えましょう。 この部分がどうしても考えられず(サイトを見てもListを二重ループしてる方法しか探すことができず) ListAとListBの比較がうまくいできませんでした。 ご回答内容分かりずらくて、申し訳ございませんがご教示いただければ助かります。
Crimson_Tide

2021/10/31 05:33 編集

コード修正の対応ありがとうございます。 できれば、import文、class文、mainメソッド文も省略せず掲載して頂いたほうが、回答しようとする人がコードをそのまま利用し確認しやすいかと思います。 比較処理の前に今一度比較するデータ(ListAとListBの中身)が想定通りか確認してみてください。 IDEのデバッグ機能を使ってもいいですし、例えば2重のfor文の前に以下のように追記して実行してみてもいいかと思います。 System.out.println("ListA:" + ListA.get(1).get("年齢") + " 要素数:" + ListA.size()); System.out.println("ListB:" + ListB.get(1).get("年齢") + " 要素数:" + ListB.size()); ListAとListBは、それぞれ二つのMAPインスタンスを保持し、2つめマップインスタンスの年齢をキーとした値がListAとListBでは異なっている(25と50)状態を想定している、と私は受け取ったのですが違うでしょうか?
jimbe

2021/10/31 05:19

> この部分がどうしても考えられず(サイトを見てもListを二重ループしてる方法しか探すことができず) 「どうしても」に対して「どうして」考えられないのかを考えてください。 プログラミングは「自分で正解を設定して組み立てるパズル」です。サイトの情報はその著者自身の正解に対する答えに過ぎず、 THE_GUTS さんの正解と同じとは限りません。 サイトからコードを得るということは、そのコードが意味するものを知るということです。コードをコピペして動かないという状況は、意味するものを知れていないと思われます。知れていないのは、コードの個々の要素、ループによる各変数の変化やそれによる比較対象の指定のされ方、比較自体の方法等のどこか、あるいは全てに知識・理解の不足があるのではないでしょうか。 それを見出して解決しなければ、ただ弄り回すか、丸投げになるでしょう。
THE_GUTS

2021/10/31 06:16 編集

Crimson_Tide様 アドバイスありがとうございます。 import文、class文、mainメソッド文の省略の件、後ほど記載します。 修正後のソースコードにてSystem.out.printlnで確認すると ListA:50 要素数:3 ListB:50 要素数:2 でした。 これは実装したいものとは異なります。 >ListAとListBは、それぞれ二つのMAPインスタンスを保持し、2つめマップインスタンスの年齢をキーとした値がListAとListBでは異なっている(25と50)状態を想定している、と私は受け取ったのですが違うでしょうか? はい、そうです。 ListA:25 要素数:2 ListB:50 要素数:2 が想定している結果となります。 jimbe様 おっしゃる通りだと思います。 まだ知識が浅いので、サイト等を参考にしながら作成していますが、知識理解の不足があるのだと思います。 List同士の比較もう少し動かしながら調べてみます。
dodox86

2021/10/31 06:31

リスト全体、リスト同士の比較もそうですが、 > if (!(map1.equals(map2))) { のような単にMapのオブジェクト同士のequals()メソッドを利用した比較で、想定した比較の結果を得られているか疑問です。「修正後のソースコード」とか「試したこと」で示されたコードも、正直、理解されているように思えない成り行きです。あれもこれも同時に一緒にやるのではなく、ひとつひとつ確実にしてから進めてはどうでしょう。現時点の質問者さんにはちょっと難しすぎる問題のように思えますが、急がなければならない何かの課題なのでしょうか。ググることを否定はしませんが、基本ができていない状態で、あちこちのサイトを見るのは振り回されるばかりだし、断片的に使えそうなコードを持ってきて完成させようとするのは無謀です。
guest

回答1

0

ベストアンサー

listAもlistBもmapAとmapBを持っているため、listAとlistBの中身が全く同じになっています。
listBには新しいmapオブジェクトをaddする必要があります。

修正後のソースコードをざっと修正すると、次のようになると思います。

Java

1var listA = new ArrayList<Map<String, Object>>(); 2 3var mapA = new HashMap<String, Object>(); 4var mapB = new HashMap<String, Object>(); 5 6// ListAに格納処理 7mapA.put("性別", "男性"); 8mapA.put("名前", "山田"); 9mapA.put("年齢", "20"); 10listA.add(mapA); 11 12mapB.put("性別", "女性"); 13mapB.put("名前", "田中"); 14mapB.put("年齢", "25"); 15listA.add(mapB); 16 17// リストAを複製 18var listB = new ArrayList<Map<String, Object>>(); 19listB.add(new HashMap<>(mapA)); 20var mapC = new HashMap<>(mapB); 21mapC.put("年齢", "50"); 22listB.add(new HashMap<>(mapC)); 23 24// ListAとListBを比較し、異なるものを条件分岐させる 25for (var i = 0; i < listA.size(); i++) { 26 if (!listA.get(i).equals(listB.get(i))) { 27 System.out.println(i); 28 // DB更新処理 29 } 30}

投稿2021/10/31 06:23

asarikz

総合スコア51

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問