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

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

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

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

Q&A

解決済

1回答

4123閲覧

2つの配列の差分を取得したい

oc_o

総合スコア1

Java

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

0グッド

0クリップ

投稿2021/10/21 07:00

編集2021/10/21 20:58

実現したいこと

独自のクラス変数型の配列を比較し、差分を取得したいです。

試したこと

下記のように配列をListに変換し、removeAllで差分のみ残そうとしましたがhashCodeが異なるため実現できないことがわかりました。

Java

1 // テストオブジェクト一覧取得 2 TestObj[] behoreObjs = getBeforeObjs(); 3 TestObj[] afterObjs= getAfterObjs(); 4 5 // 配列→Listに変換 6 List<TestObj> behoreObjList = new ArrayList<TestObj>(Arrays.asList(behoreObjs)); 7 List<TestObj> afterObjList = new ArrayList<TestObj>(Arrays.asList(afterObjs)); 8 9 if (!afterObjList.equals(behoreObjList)) { 10 if (afterObjList.removeAll(behoreObjList)) { 11 for (TestObj obj : afterObjList) { 12 // 差分オブジェクトを削除 13 delete(obj); 14 } 15 } 16 }

TestObjは一意のIDを保持しているため、equalsをオーバーライドしIDを比較することも検討しましたが、TestObjクラスに手を加えたくありません。

この場合、どのように差分を取得するのがスマートでしょうか?

開発環境

Java 1.7

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

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

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

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

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

jimbe

2021/10/21 07:51

TestObj の扱いにおいて ID が同じなら同じオブジェクト(データ)であるのでしたら、 equals をオーバーライド "すべき" と思いますが、なぜ手を加えたくないのでしょうか。
oc_o

2021/10/21 18:18

コメントありがとうございます。 今回新機能のテストケースでTestObjを扱いたく、テストケースのために既存クラス(TestObj)に手を加えるのを躊躇ったためです。
jimbe

2021/10/21 19:02 編集

「同じオブジェクトで無ければ同一と判断しない」というのが TestObj の equals の仕様であれば変更出来ませんが、そうで無いならば TestObj の不備が見つかったことになります。さらに、テストに必要な機能であればそれを直すのが先に思えますが、如何でしょう。 また逆に equals の仕様がそうであれば、getBeforeObjs と getAfterObjs が返した中で同一の ID のオブジェクトは同じオブジェクトでなければならないのですから、そうなっていないならどちらかのメソッドのバグと判断しなければならないようにも思います。
swordone

2021/10/21 19:54

> TestObjは一意のIDを保持しているため、equalsをオーバーライドしIDを比較することも検討しましたが じゃあこのコード内で使っているequalsは、オーバーライドしていないObjectのequalsと同じものという事ですか?
oc_o

2021/10/21 21:03

>jimbeさん なるほど…既存の影響範囲の広さからなんとなく敬遠してしまっていたのですがそのあたりも考えてみます。 >swordoneさん 試したことに記載しているコードのequalsはObjectのequalsです。 そのため期待していたTestObjの内容が全く同じかという判断はできていません。(こちらについてはremoveAllが期待した動きにならないことで気付き学びました。)
guest

回答1

0

ベストアンサー

TestObjに一意のidが存在するということなので、getId()メソッドが存在する想定で記載しています。

Java

1 // beforeObjsからidを抽出し、リスト化 2 List<String> ids = Arrays.stream(beforeObjs).map(TestObj::getId) 3 .collect(Collectors.toList()); 4 5 // beforeのidリストに含まれないという条件でafterObjsをfilterし 6 // 残ったものをリスト化 7 List<TestObj> list = Arrays.stream(afterObjs) 8 .filter(testObj -> !ids.contains(testObj.getId())) 9 .collect(Collectors.toList()); 10

投稿2021/10/21 07:35

Luice

総合スコア771

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

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

oc_o

2021/10/22 01:24 編集

回答ありがとうございます。 記載できたいなかったのですが開発環境がJava7のため使用できないAPIのようです…。
oc_o

2021/10/22 01:40 編集

失礼しました。調べてみたらJava7でも同じことはできるんですね。 参考にやりたかったことが実現できました。ありがとうございました!
swordone

2021/10/22 02:57

StreamはJava8からの機能だから、7では使えないのでは?
Luice

2021/10/22 03:27

stream apiはJava8からですが、ライブラリを活用したり処理を分解して実装すれば 同じ事を実現することは可能ですよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問