質問は簡単です:
私は2つのリストを持っています
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
そして、これらの共通部分を取得する必要があります。これを達成する簡単な方法はありますか?
retainAll
メソッドを使用できます:
columnsOld.retainAll (columnsNew);
RetainAllは引数コレクションに触れないため、これはより高速になります。
List<String> columnsOld = DBUtils.GetColumns(db, TableName);
List<String> columnsNew = DBUtils.GetColumns(db, TableName);
for(int i = columnsNew.size() - 1; i > -1; --i){
String str = columnsNew.get(i);
if(!columnsOld.remove(str))
columnsNew.remove(str);
}
交差点は、columnsNewに残っている値になります。 columnsOldからすでに比較された値を削除すると、必要な比較の回数が減ります。
どう?
private List<String> intersect(List<String> A, List<String> B) {
List<String> rtnList = new LinkedList<>();
for(String dto : A) {
if(B.contains(dto)) {
rtnList.add(dto);
}
}
return rtnList;
}
1行のコードでこれを行うことができるストリームにはいい方法があり、containsAllメソッドafaikでは不可能な、同じタイプではない2つのリストを作成できます。
columnsOld.stream().filter(c -> columnsNew.contains(c)).collect(Collectors.toList());
さまざまなタイプのリストの例。 fooとbarの間に関係があり、fooからbarオブジェクトを取得できる場合は、ストリームを変更できます。
List<foo> fooList = new ArrayList<>(Arrays.asList(new foo(), new foo()));
List<bar> barList = new ArrayList<>(Arrays.asList(new bar(), new bar()));
fooList.stream().filter(f -> barList.contains(f.getBar()).collect(Collectors.toList());
2番目のリストをセットに入れる場合は、HashSetと言います。そして、最初のリストを繰り返し処理して、セットに存在するかどうかを確認し、存在しない場合は削除すると、最初のリストに最終的に必要な共通部分ができます。 retainAllやリストに含まれるよりもずっと高速です。ここでの重点は、リストの代わりにセットを使用することです。ルックアップはO(1)です。 firstList.retainAll(新しいHashSet(secondList))も機能します。
org.Apache.commons.collections4.ListUtils#intersectionを使用します
発生を気にしない場合はretainAllを使用し、そうでない場合はN.intersectionを使用する
a = N.asList(12, 16, 16, 17, 19);
b = N.asList(16, 19, 107);
a.retainAll(b); // [16, 16, 19]
N.println(a);
a = N.asList(12, 16, 16, 17, 19);
b = N.asList(16, 19, 107);
a = N.intersect(a, b);
N.println(a); // [16, 19]
Nは AbacusUtil のユーティリティクラスです