5

Javaでは、2つのリストがあるとします

List<Object1> list1
List<Object2> list2

object1.getName(); returns a String
object2.getName(); return a String

名前を比較して、2 つのリストの違いを取得する方法はありますか

これらの 2 つのオブジェクトはサード パーティのライブラリで定義されており、equals メソッドと compareto メソッドをオーバーライドできません。

私はグーグルグアバまたはコモンズコレクションライブラリに賛成です

しかし、Sets.symmetricDifference(Set1, Set2)2 を渡すように要求します。Sets.newHashSet(lis1) と Sets.newHashSet(lis2) を使用して 2 つのセットを作成しても、セット内のオブジェクトのタイプが異なります。

またはコモンズCollectionUtils.disjunction(lis1, list2)では、リストには同じオブジェクトタイプが含まれている必要があります

2 つの高価な for ループを実行せずに、他の方法はありますか?

4

3 に答える 3

1

グアバを使って、これを試してください。それは私のために働く - >

Multisets.difference(multiset1,multiset2);

ArrayList を Multiset に変換する方法。

 List x = new ArrayList();
 x.add(3);.....

 Multiset newX = HashMultiset.create();
 newX.addAll(x);
于 2014-09-10T11:59:07.090 に答える
1

まず、リストを文字列ベースのリストに変換する必要があります。

private static final class FromObject1ToName implements Function<Object1, String> {
    @Override
    public String apply(Object1 input) {
        return input.name;
    }
}

Object2 に対しても同じ変換を行う必要があります。

次に、入力リストを変換します。

 Collection<String> transformed = Collections2.transform(list1, new FromObject1ToName());

//list1 は Object1 のリストです

次に、マルチセットを作成します。

 Multiset<String> multiset1 = HashMultiset.create();
    multiset1.addAll(transformed);

次に、次のようにします。

 Multisets.difference(multiset1, multiset2) // multiset1 is from Object1 and multiset2 is from Object2

これにより、違いとそれが何回異なるかがわかります

違いだけを知る必要がある場合は、同じ変換を行い、文字列のコレクションを Set にロードしてから Sets.symmetricDifference を実行します。

于 2014-09-10T14:08:52.773 に答える
1

まず、リストごとに 1 つずつ、2 つのマップを作成し、名前をオブジェクトにマッピングします。次に、キーセット間の違いを繰り返し処理し、その名前を持つオブジェクトの種類を処理します。マップを使用すると、リストをスキャンしてその名前のオブジェクトを探す必要がなくなります。(Multimap ではなく Map を使用する場合、各リスト内で名前が一意であるという別の回答に対する質問者のコメントに依存しています。まだ Java 7 を使用している場合は、メソッド参照を Function 実装に置き換えてください。)

Map<String, Object1> map1 = Maps.uniqueIndex(list1, Object1::getName);
Map<String, Object2> map2 = Maps.uniqueIndex(list2, Object1::getName);
for (String name : Sets.difference(map1.keySet(), map2.keySet()))
    processObject1(map1.get(name));
for (String name : Sets.difference(map2.keySet(), map1.keySet()))
    processObject2(map2.get(name));

リストまたはオブジェクトのセットを正確に 1 つのリストに作成するだけで、オブジェクトをコレクションに追加するだけprocessObject1でよい場合。processObject2

uniqueIndexの反復順序は入力differenceイテラブルの反復順序であり、最初の引数と同じ反復順序で SetView を返すため、その順序が問題に関連している場合は、入力リストに表示された順序でオブジェクトを処理できます。


Java 8 ストリームは、基本的に同じ機能を提供します。

Map<String, Object1> map1 = list1.stream().collect(Collectors.toMap(Function.identity(), Object1::getName));
Map<String, Object2> map2 = list2.stream().collect(Collectors.toMap(Function.identity(), Object2::getName));
map1.keySet().stream().filter(n -> !map2.keySet().contains(n)).map(map1::get).forEachOrdered(o1 -> processObject1(o1));
map2.keySet().stream().filter(n -> !map1.keySet().contains(n)).map(map2::get).forEachOrdered(o2 -> processObject1(o2));

繰り返しますが、オブジェクトを収集するだけの場合は、forEachOrdered呼び出しを に置き換えることができます。collect(Collectors.toList())

于 2014-09-17T22:49:00.217 に答える