【问题标题】:Merge single objects and list of objects into a single list of objects in Java将单个对象和对象列表合并到Java中的单个对象列表中
【发布时间】:2018-12-14 06:18:18
【问题描述】:

给定一个对象列表

// ["A", ["B", null, "C"], "D", ["E"], [], null, "F"];
List<Object> objects = Arrays.asList("A", Arrays.asList("B", null, "C"), "D", Arrays.asList("E"), Arrays.asList(), null, "F");

有没有一种简单的方法可以将非空值组合成一个列表["A", "B", "C", "D", "E", "F"]

你们中的一些人坚持帖子必须显示尝试过的内容

objects.stream().map(o -> {
        if (o instanceof List) {
            return ((List) o).stream();
        } else return objects.stream();
    }).filter(Objects::nonNull).collect(Collectors.toList()));

显然上述方法不起作用。

【问题讨论】:

  • 请问您是如何得到这个锯齿状列表数据结构的?几乎感觉它可能来自 JSON。
  • @TimBiegeleisen 它来自对象地图,然后被展平为对象列表,但是您想知道地图的来源?如果有帮助,是的 JSON?
  • List&lt;Object&gt; !!你应该检查所有可能的类型。其余的人呢? JSON 仍然以不同的方式处理数字,对吧?

标签: java list arraylist java-8 java-stream


【解决方案1】:

如果只有两层嵌套,而不是递归列表中更深的列表, 那么这是一种扁平化的方法:

List<String> flat = objects.stream()
  .filter(Objects::nonNull)
  .flatMap(v -> {
    if (v instanceof String) {
      return Stream.of((String) v);
    }
    return ((List<String>) v).stream().filter(Objects::nonNull);
  })
  .collect(Collectors.toList());

如果可以递归嵌套更深层次, 然后您可以将上述内容包装在一个函数中并递归应用它(感谢@Holger 使其更紧凑):

List<String> flatten(List<?> objects) {
  return objects.stream()
    .filter(Objects::nonNull)
    .flatMap(v -> v instanceof String
      ? Stream.of((String) v)
      : flatten((List<?>) v).stream())
    .collect(Collectors.toList());
}

【讨论】:

  • 谢谢@janos!你认为你准备好迎接挑战做一个递归版本了吗?
  • 或更短:List&lt;String&gt; flatten(List&lt;?&gt; objects) { return objects.stream() .filter(Objects::nonNull) .flatMap(v -&gt; v instanceof String? Stream.of((String)v): flatten((List&lt;?&gt;)v).stream()) .collect(Collectors.toList()); }
猜你喜欢
  • 2022-10-17
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
  • 2019-03-27
  • 2018-04-21
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
相关资源
最近更新 更多