こんにちは、うえだです。
Javaで、ListやMapの内容を全て取り出して並べたいとき、各要素を再帰的に取得して出力する必要があります。
Java Stream APIにはflatMapという、ネストされた処理(Stream.map)の結果を1つのストリームとして返す関数が用意されているので、それを使用すると、この処理も比較的簡単に作れます。
今回はMap、Collection、配列、およびStreamを対象にしてみました。
- Map、Collection、またはObjectの配列を再帰的に平滑化
- Mapはエントリ毎にキー、値の順に平滑化
- 出力順はコンテナ内の順序の扱いに依存する(順不定のコンテナなら順不定で出力する)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public static Stream<Object> flatten(Object o) {
if (o instanceof Object[]) {
return Arrays.stream((Object[]) o).flatMap(e -> flatten(e));
} else if (o instanceof Map<?, ?>) {
return ((Map<?, ?>) o).entrySet().stream()
.flatMap(e -> Stream.concat(flatten(e.getKey()), flatten(e.getValue())));
} else if (o instanceof Collection<?>) {
return ((Collection<?>) o).stream().flatMap(e -> flatten(e));
} else if (o instanceof Stream<?>) {
return ((Stream<?>) o).flatMap(e -> flatten(e));
}
return Stream.of(o);
}
|
- 実行例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static void main(String[] args) {
List<Object> d = Arrays.asList(Arrays.asList("1", new Object[] { "11", new HashMap<String, Object>() {
{
put("AA", "00");
put("AB", Arrays.asList("0", "1", new Object[] { "11", new TreeMap<String, Object>() {
{
put("VAA", "V00");
put("VAB", Arrays.asList("V0", "V1"));
put("VCC", 322);
}
}, "V12" }));
put("CC", 22);
}
}, "12" }), "3");
System.out.println(flatten(d).map(Object::toString).collect(Collectors.joining("\n")));
}
|
- 結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
1
11
AA
00
CC
22
AB
0
1
11
VAA
V00
VAB
V0
V1
VCC
322
V12
12
3
|
以上です。何かの参考になれば幸いです。