如何创建 <Interface> 对象流?

How can I create a stream of <Interface> objects?

假设我有:

interface SomeInterface {       
   Foo getFoo();
}

class SomeClass implements SomeInterface {
    Foo getFoo() {
       //returns a Foo object
    }
}

然后在服务中,我有:

List<SomeClass> getItems() {
   //returns a list of SomeClass objects
}

不允许进行以下操作:

Stream<SomeInterface> items = service.getItems().stream();

但最终,我还有其他 classes 会共享此界面并希望这样做:

someMethod(Stream<SomeInterface> items) {
   //some operation
}

有办法解决这个问题吗?喜欢使用 flatMap? (我注意到,如果我在 SomeClass 个对象的 List 上有一个包装器 class,我可以 flatMap 包装器 return SomeInterface 个对象。)

我没有找到类似的问题,也不容易看到解决方案。可能是我想念的容易的事情。 Java14.

一个选项是使用强制转换显式映射流:

Stream<SomeInterface> items = service.getItems().stream().map(SomeInterface.class::cast);

为什么不直接将 getItems() return 设为 List<SomeInterface>

的列表
public List<SomeInterface> getItems()

然后只需调用:

Stream<SomeInterface> items = service.getItems().stream();

与评论中指出的类似的另一个选项是:

Stream<? extends SomeInterface> stream = service.getItems().stream();

如果您不能更改 getItems() 的方法签名,您可以映射流:

import java.util.List;
import java.util.ArrayList;
import java.util.stream.Stream;

public class StreamsDemo {
    
    static interface SomeInterface {
        String getFoo();
    }

    static class SomeClass implements SomeInterface {
        @Override
        public String getFoo() {
            return "hello";
        }
    }

    static class SomeService {

        List<SomeClass> getFoos() {
            List<SomeClass> list = new ArrayList<>();
            list.add(new SomeClass());
            list.add(new SomeClass());
            return list;
        }
    }

    public static void main(String... args) {
        Stream<SomeInterface> stream = new SomeService().getFoos()
                                                        .stream()
                                                        .map(SomeInterface.class::cast);
        stream.forEach(some -> System.out.println(some.getFoo()));
    }
}

无需更改任何其他内容,您可以只使用 java 通配符和泛型。

Stream<? extends SomeInterface> items = service.getItems().stream();

? 的意思是“任何扩展接口 SomeInterface 的东西”,这将适用于您的 SomeClass(以及任何其他 class扩展该接口)

更多信息:https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

示例代码:

    public static void main(String args[]) {
    
            SomeService service = new SomeService();
            Stream<? extends SomeInterface> stream = service.getItems().stream();
        }
    
        public static class Foo {
    
        }
    
        public static interface SomeInterface {
            Foo getFoo();
        }
    
        public static class SomeClass implements SomeInterface {
            @Override
            public Foo getFoo() {
                return null;
            }
        }
    
        public static class SomeService {
            public List<SomeClass> getItems() {
                return new ArrayList<>();
            }
        }
    }

如果您的目标是让 someMethod 接受 SomeInterface 接口的流及其子类型,那么您可以使用

/*someReturnTypeHere*/ someMethod(Stream<? extends SomeInterface> items){
   //some operation
}