データによるグループ化にはJava 8を使用します。ただし、得られた結果は順序どおりではありません。
Map<GroupingKey, List<Object>> groupedResult = null;
if (!CollectionUtils.isEmpty(groupByColumns)) {
Map<String, Object> mapArr[] = new LinkedHashMap[mapList.size()];
if (!CollectionUtils.isEmpty(mapList)) {
int count = 0;
for (LinkedHashMap<String, Object> map : mapList) {
mapArr[count++] = map;
}
}
Stream<Map<String, Object>> people = Stream.of(mapArr);
groupedResult = people
.collect(Collectors.groupingBy(p -> new GroupingKey(p, groupByColumns), Collectors.mapping((Map<String, Object> p) -> p, toList())));
public static class GroupingKey
public GroupingKey(Map<String, Object> map, List<String> cols) {
keys = new ArrayList<>();
for (String col : cols) {
keys.add(map.get(col));
}
}
// Add appropriate isEqual() ... you IDE should generate this
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final GroupingKey other = (GroupingKey) obj;
if (!Objects.equals(this.keys, other.keys)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + Objects.hashCode(this.keys);
return hash;
}
@Override
public String toString() {
return keys + "";
}
public ArrayList<Object> getKeys() {
return keys;
}
public void setKeys(ArrayList<Object> keys) {
this.keys = keys;
}
}
ここで私は私のクラスgroupingKeyを使用しています。これにより、uxから動的に渡されます。このgroupByColumnsをソートされた形式で取得するにはどうすればよいですか?
順序を維持しないのは、結果を格納するMap
のプロパティです。特定のMap
動作が必要な場合は、 特定のMap
実装を要求 する必要があります。例えば。 LinkedHashMap
は挿入順序を維持します:
_groupedResult = people.collect(Collectors.groupingBy(
p -> new GroupingKey(p, groupByColumns),
LinkedHashMap::new,
Collectors.mapping((Map<String, Object> p) -> p, toList())));
_
ちなみに、mapList
を作成する前に、Stream
の内容を配列にコピーする必要はありません。 mapList.stream()
を呼び出すだけで、適切なStream
を取得できます。
さらに、Collectors.mapping((Map<String, Object> p) -> p, toList())
は廃止されました。 _p->p
_はIDマッピングであるため、mapping
を要求する理由はまったくありません。
_groupedResult = mapList.stream().collect(Collectors.groupingBy(
p -> new GroupingKey(p, groupByColumns), LinkedHashMap::new, toList()));
_
しかし、GroupingKey
でさえ時代遅れです。基本的にList
の値をラップするので、そもそもList
をキーとして使用するだけで済みます。 List
sはhashCode
およびequals
を適切に実装します(ただし、してはいけませんこれらのキーを変更してくださいList
sその後)。
_Map<List<Object>, List<Object>> groupedResult=
mapList.stream().collect(Collectors.groupingBy(
p -> groupByColumns.stream().map(p::get).collect(toList()),
LinkedHashMap::new, toList()));
_
@Holgerの素晴らしい答えに基づいています。これを投稿して、グループ化やマッピングの変更後も順序を維持したい人を支援します。
単純化して、人のリスト(int age、String name、String adresssなど)があり、年齢を順番に保ちながら年齢別にグループ化したいとします。
final LinkedHashMap<Integer, List<String> map = myList
.stream()
.sorted(Comparator.comparing(p -> p.getAge())) //sort list by ages
.collect(Collectors.groupingBy(p -> p.getAge()),
LinkedHashMap::new, //keep the order
Collectors.mapping(p -> p.getName(), //map name
Collectors.toList())));