为何Iterable<>作为返回类型无法使用.collect(Collectors.toList())?及代码简化方案
问题解答
1. 为什么Iterable<>不能直接调用.collect(Collectors.toList())?
其实核心原因很简单:Java的Iterable接口本身并没有集成Stream API的相关方法。collect()是Stream接口的专属方法,而Iterable只是一个定义了基础迭代能力的接口——它只要求实现类提供iterator()方法,并没有内置转成Stream的默认实现。
对比一下Collection接口(它继承了Iterable),Java 8之后给Collection添加了stream()默认方法,所以List、Set这些Collection的子类都能直接调用stream().collect(...)。但Iterable本身没有这个扩展,直接调用collect()编译器肯定会报错哦。
2. 如何用Lambda/Stream API简化你的代码?
要解决这个问题,关键是把Iterable<CloudBlobContainer>转换成Stream,之后就能用collect(Collectors.toList())一步到位了。用JDK原生工具类就能实现,不需要额外依赖,直接通过StreamSupport.stream()包装Iterable的迭代器即可:
List<String> list = StreamSupport.stream( client.listContainers().spliterator(), false // 表示是否使用并行流,这里串行流就足够了 ).map(CloudBlobContainer::getName) .collect(Collectors.toList());
如果你想更明确地处理迭代器(比如不确定spliterator的实现情况),也可以用Spliterators.spliteratorUnknownSize()生成spliterator:
List<String> list = StreamSupport.stream( Spliterators.spliteratorUnknownSize( client.listContainers().iterator(), Spliterator.ORDERED ), false ).map(c -> c.getName()) // 也可以用方法引用CloudBlobContainer::getName简化 .collect(Collectors.toList());
这样就完全不需要提前创建ArrayList了,一行代码就能完成从Iterable到目标List的转换,完美满足你简化代码的需求~
内容的提问来源于stack exchange,提问作者menteith
相关产品推荐
相关产品推荐

