こんにちは、うえだです。
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 |
以上です。何かの参考になれば幸いです。