Bionix1441:
私は現在、Javaでのデータ構造を実現しようとしている、と同じフィールドを有するオブジェクトの異なるサブセットに、入力オブジェクトの集合を分割したいです。
An example use case
:
私たちは、特定の日付を生まれて人物のサブリストに人物のリストを分割したいです。
Input
:1990年生まれPERSON1、2000年生まれPERSON2、1990年生まれのperson3。
Output
:
1 - > PERSON1、person3
2 - > PERSON2
public Map<Integer, List<Foo>> getIntToFooMap(List<Foo> foos) {
Map<Integer, List<Foo>> map = new TreeMap<>(); // need keys to be automatically ordered.
List<Foo> foosWithSameSetId = new ArrayList<>();
if (!foos.isEmpty) {
for (Foo foo: foos) {
for (Foo foo2: foos) {
if (foo.getSetId().equals(foo2.getSetId())) {
foosWithSameSetId.add(foo2);
}
}
map.put(foo.getSetId(), foosWithSameSetId);
foosWithSameSetId.clear();
}
}
return map;
}
上記のコードは最適ではない、時間の複雑さは二次であり、また、スレッドセーフではありません。誰かがこのような場合には、同じフィールドを持つオブジェクトのサブセットにリストまたはセットを分割するより良い方法を教えてもらえますsetId
。
ernest_k:
まず、ネストされたループは必要ありません。あなただけの取得または現在のセットを作成したいfoo
のがsetId
、そして追加しfoo
、それに:
for (Foo foo : foos) {
map.computeIfAbsent(foo.getSetId(), i -> new ArrayList<>()).add(foo);
}
これに相当します。
for (Foo foo : foos) {
List<Foo> list = map.get(foo.getSetId());
if(null == list) list = new ArrayList<>();
list.add(foo);
}
さて、あなたは心の中で時間保持する必要があるマップの実装のための複雑さを。
別の方法として、groupingBy
ストリームのコレクタは、あなたのコードに簡潔に追加します。
return foos.stream().collect(
Collectors.groupingBy(Foo::getSetId, TreeMap::new, Collectors.toList()));