【问题标题】:Flatten a nested N-Level nested object in java在java中展平嵌套的N级嵌套对象
【发布时间】:2019-03-18 10:39:32
【问题描述】:

我有一个java类

class Example{
   String field1;
   String field2;
   List<Example> subExamples;    
}

在上述场景中,Example 有 subExamples,它又是一个 Example 列表。这种嵌套可以是 n 级。我想要实现的是拥有一个示例列表,即将上述对象展平并将所有示例收集到最终列表中(收集所有 n 级示例)。一种明显的方法是递归。 Java中有什么方法可以更有效地实现它。我尝试了一些 java 8 概念,但它们不符合要求。

【问题讨论】:

  • flatMap 带有递归。另见this
  • 你可以使用Queue代替递归
  • @Flown 很有趣,但我看不出没有递归怎么可能。可以提供答案吗?
  • @Eugene 看我的回答,它是广度优先搜索的一种实现(也可以采用深度优先搜索的方式)。

标签: java collections java-8 java-stream


【解决方案1】:

例如:

private static Stream<Example> flat(Example example) {
    return Stream.concat(Stream.of(example),
                         example.getSubExamples().stream().flatMap(Sandbox::flat));
}

其中Sandbox 是定义flat 方法的类。

【讨论】:

  • 嗨@Eugene 在这里使用parallelStream() 可以提高效率,对吧?
  • @codeluv 如果你有 很多 元素,可能是,但我对此表示怀疑。
【解决方案2】:

您可以使用的简单方法:

static Stream<Example> flatten(Example ex) {
    if (ex.getSubExamples() == null || ex.getSubExamples().isEmpty()) {
        return Stream.of(ex);
    }

    return Stream.concat(Stream.of(ex), 
                ex.getSubExamples().stream().flatMap(Main::flatten));
}

你可以用作什么

List<Example> flattened = examples.stream()
        .flatMap(Main::flatten) //change class name
        .collect(Collectors.toList());

【讨论】:

  • 由于开发人员永远不应该让List 属性变为null 并且无论如何流都会正确处理空列表,因此if 语句已过时。
【解决方案3】:

这可以以非递归方式完成:

private Collection<Example> flatten(Example example) {
  Queue<Example> work = new ArrayDeque<>();
  if (example != null) {
    work.offer(example);
  }
  Collection<Example> flattened = new ArrayList<>();
  while(!work.isEmpty()) {
    Example cur = work.poll();
    flattened.add(cur);
    cur.subExamples.forEach(work::offer);
  }
  return flattened;
}

【讨论】:

    猜你喜欢
    • 2018-10-24
    • 2017-07-02
    • 2020-12-22
    • 2019-07-20
    • 2018-10-28
    • 1970-01-01
    • 2021-10-19
    • 2020-06-23
    • 2012-05-29
    相关资源
    最近更新 更多