Java 平面地图嵌套集合

Java 平面地图嵌套集合,java,java-stream,flatmap,Java,Java Stream,Flatmap,我有一个对象列表,其中一些可以是集合。我想得到一个简单的对象流 List<Object> objects = List.of(1, 2, "SomeString", List.of(3, 4, 5, 6), 7, List.of("a", "b", "c"), List.of(8, List.of(9, List.of(10)))); 我试过了 Function<Object, Stream<Object>> mbjectToStreamM

我有一个对象列表,其中一些可以是集合。我想得到一个简单的对象流

List<Object> objects = List.of(1, 2, "SomeString", List.of(3, 4, 5, 6), 
    7, List.of("a", "b", "c"),
    List.of(8, List.of(9, List.of(10))));
我试过了

Function<Object, Stream<Object>> mbjectToStreamMapper = null; //define it. I have not figured it out yet!
objects.stream().flatMap(ObjectToStreamMapper).forEach(System.out::println);
函数mbjectToStreamMapper=null//定义它。我还没弄明白呢!
objects.stream().flatMap(objecttostreamapper.forEach(System.out::println);
我还检查了一个示例,它显示了如何使用一个递归函数来展平集合。但是,在本例中,
.collect(Collectors.toList())用于保留中间结果
Collectors.toList()
是一个终端操作,它将立即开始处理流。我想得到一个流,我可以在以后迭代


更新 我同意这些评论,拥有一个由不同性质的对象组成的流是一个可怕的想法。我写这个问题只是为了简单。在现实生活中,我可以监听不同的事件,并处理来自传入流的一些业务对象,其中一些可以发送对象流,其他的-只是单个对象。

类循环{
class Loop {
    private static Stream<Object> flat(Object o) {
        return o instanceof Collection ?
                ((Collection) o).stream().flatMap(Loop::flat) : Stream.of(o);
    }

    public static void main(String[] args) {
        List<Object> objects = List.of(1, 2, "SomeString", List.of( 3, 4, 5, 6),
                7, List.of("a", "b", "c"), List.of(8, List.of(9, List.of(10))));

        List<Object> flat = flat(objects).collect(Collectors.toList());

        System.out.println(flat);
    }
}
私有静态流平面(对象o){ 返回集合的o实例? ((Collection)o.stream().flatMap(Loop::flat):stream.of(o); } 公共静态void main(字符串[]args){ List objects=List.of(1,2,“SomeString”,List.of(3,4,5,6), 第7条名单(“a”、“b”、“c”)、第8条名单、第9条名单、第10条名单); List flat=flat(对象).collect(收集器.toList()); 系统输出打印LN(平面); } }

请注意
List.of(null)
抛出NPE。

如果要遍历的对象是
集合的实例,我们可以递归地获取嵌套的

public static void main(String args[]) {
       List<Object> objects = List.of(1, 2, "SomeString", List.of(3, 4, 5, 6),
            7, List.of("a", "b", "c"),
            List.of(8, List.of(9, List.of(10))));
       List<Object> list = objects.stream().flatMap(c -> getNestedStream(c)).collect(Collectors.toList());
}

public static Stream<Object> getNestedStream(Object obj) {
    if(obj instanceof Collection){
        return ((Collection)obj).stream().flatMap((coll) -> getNestedStream(coll));
    }
    return Stream.of(obj);
}
publicstaticvoidmain(字符串参数[]){
List objects=List.of(1,2,“SomeString”,List.of(3,4,5,6),
第7条(“a”、“b”、“c”)清单,
名单(八,九,十);;
List List=objects.stream().flatMap(c->getNestedStream(c)).collect(collector.toList());
}
公共静态流getNestedStream(对象obj){
if(集合的obj实例){
return((Collection)obj.stream().flatMap((coll)->getNestedStream(coll));
}
回流流量(obj);
}

注意,可以在字段中定义递归方法:

public class Test {
  static Function<Object,Stream<?>> flat=
    s->s instanceof Collection ? ((Collection<?>)s).stream().flatMap(Test.flat) : Stream.of(s);
  public static void main(String[] args) {
    objects.stream().flatMap(flat).forEach(System.out::print);
  }
}
公共类测试{

静态函数“我有一个对象列表,其中一些可以是集合。”除非您的实际对象有一个更有用的通用超类型,否则在没有某种反射的情况下,您几乎无法实际使用此列表(不考虑流)。因此解决方案(几乎)不可避免地会涉及反射。你确定需要将所有这些对象存储在同一个列表中吗?听起来是个可怕的想法me@LászlóStahorszki,是的,我同意你的观点。只是为了简单起见。例如,我需要处理事件、更新事件、复杂事件,它们来自不同的来源。正如我在更新中所写的。我非常确定您可以创建一个公共接口,所有列表成员都可以实现。不要将这种混合放在任何地方。而是将这些东西包装在一个对象中,该对象实现一个包含流方法的公共接口。然后您就有了
list
,它更好,可以使用
objects.stream().flatMap进行处理(MyStreamableThing::toStream)
这里不需要过滤,因为List.of接受非空参数。即使我用空值传递新ArrayList的List.of,它也可以工作。如果
obj
不是集合实例,则不需要
c
public class Test {
  static Function<Object,Stream<?>> flat=
    s->s instanceof Collection ? ((Collection<?>)s).stream().flatMap(Test.flat) : Stream.of(s);
  public static void main(String[] args) {
    objects.stream().flatMap(flat).forEach(System.out::print);
  }
}