如何创建 <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
}
假设我有:
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
}