如何从通用集合中获取流?

时间:2016-07-27 13:27:57

标签: java java-8 java-stream

我有一个Object作为参数的函数。此对象可能可能是最一般意义上的集合:它可以是列表,地图,可迭代等,在这种情况下,我想处理属于它的每个项目:

public void f(Object o) {
    if (o instanceof SOMECLASSORINTERFACE<?>) {
        Stream.of(o).map( .. )...;
    } else {
        // o is scalar
        ...
    }
}

上面的代码不起作用:Stream.of()不会将我的对象拆分为要流的元素,而只输出一个元素,即对象o本身。

我无法使用o.stream().map...,因为o过于通用,可能没有stream方法。

o投放到Collection不起作用。此外,检查Collection成员身份可能正确的事情操作

那么如何从泛型集合中获取流?

3 个答案:

答案 0 :(得分:3)

正确的做法肯定是不要有一个Object的函数,而是使用函数oberloading并考虑你可能采取的措施:

  • Collection<T> - 确实有一个.stream(),涵盖了大多数情况,例如ListSet等。
  • {li> Map<K,V>不在Collection<T>覆盖,但.entrySet().keySet()等等。{/ li>
  • Iterable<T>必须与您已提及的StreamSupport.stream(((Iterable<?>) o).spliterator(), false)分开处理。

因此,为上述三种情况创建三个函数,您可能会很好:

public <T> void f(Stream<T> s) {
    s.map( .. )
        .forEach(System.out::println);
}

public void f(Collection<?> o) {
    f(o.stream());
}

public void f(Map<?,?> m) {
    f(m.entrySet().stream());
}

public void f(Iterable<?> i) {
    f(StreamSupport.stream(i.spliterator(), false));
}

public void f(Object o) {
    // for the cases none of the others match
    System.out.println(o);
}

答案 1 :(得分:1)

我目前的解决方案是测试Iterable(请参阅Convert Iterable to Stream using Java 8 JDK)和Map会员资格:

public void f(Object o) {
    if (o instanceof Iterable<?>) {
        StreamSupport.stream(((Iterable<?>) o).spliterator(), false).map(e -> ...
    } else if (o instanceof Map<?,?>) {
        ((Map<?,?>) o).entrySet().stream().map(e -> ... 
    } else {
        // scalar object
       ...
    }
}

答案 2 :(得分:1)

如果您的ObjectCollection<?>而您希望将其视为Collection<?>,则将其投放。

public void f(Object o) {
    if (o instanceof Collection<?>) {
        Collection<?> c = (Collection<?>)o;
        c.stream().map(...).forEach(System.out::println);
    } else {
        System.out.println(o);
    }
}