因此,如果您想要找到任何客户的任何电话号码,第一个代码就可以了.
但是如果你喜欢第二种变体,我可以帮助你.问题是你假设了错误的数据.为了清楚起见,我在代码的每一行都添加了类型:
String b = obj.getCustomer().getDetails().stream() //Stream<CustomerDetail>
.findAny() //Optional<CustomerDetail>
.map(CustomerDetail::getContact) //Optional<Contact>
.map(Contact::getMobiles) //Optional<Set<String>>
.stream() //Stream<Set<String>> Mistake right here!
.findAny() //Optional<Set<String>>
.map(o -> o.getNumber()) // o must be Set<String>!
.orElse(null);
(我假设您的Java-8标记是错误的,因为您使用了OPTIONAL的stream()-方法,该方法仅在Java 9:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Optional.html#stream()之后才存在)
它所做的基本上是将可选元素转换为一个只有一个(或零个)元素的流,其中只包含可选元素的元素.
要解决此问题,您需要执行以下操作:
String b = obj.getCustomer().getDetails().stream() //Stream<CustomerDetail>
.findAny() //Optional<CustomerDetail>
.map(CustomerDetail::getContact) //Optional<Contact>
.map(Contact::getMobiles) //Optional<Set<String>>
.stream() //Stream<Set<String>>
.flatMap(Collection::stream) // Stream<String> new flat map to turn into a Stream of Strings
.findAny() //Optional<String>
.map(o -> o.getNumber()) // o is String and compiles
.orElse(null);
编辑:
基本上,变化所做的就是简单地"解包"集合.
你的代码基本上是一个流,里面只有一个集合.调用Collection::stream
将Set转换为Stream(使用从接口Collection
继承的stream()
-Method).现在,流中将有另一个包含所有移动设备的流.这就是为什么它必须与flatMap而不是map一起使用,后者基本上将第二个流解包到外部流中.这导致现在将一个客户的所有手机都放在流中.
如果你喜欢这个代码是不是更好,现在由你来决定.