我正在寻找一种简洁的方法来将Iterator
一个Stream
或更具体的转换为"视图"迭代器作为流.
出于性能原因,我想在新列表中避免使用迭代器的副本:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();
Run Code Online (Sandbox Code Playgroud)
根据评论中的一些建议,我也尝试使用Stream.generate
:
public static void main(String[] args) throws Exception {
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = Stream.generate(sourceIterator::next);
targetStream.forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到了NoSuchElementException
(因为没有调用hasNext
)
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:364)
at Main$$Lambda$1/1175962212.get(Unknown Source)
at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)
at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at Main.main(Main.java:20)
Run Code Online (Sandbox Code Playgroud)
我已经看过StreamSupport
和Collections
,但我没有发现任何东西.
我有一个返回的界面java.lang.Iterable<T>
.
我想使用Java 8 Stream API来操纵该结果.
但是Iterable不能"流".
知道如何将Iterable用作Stream而不将其转换为List吗?
在Java 8中,我们有Stream <T>类,它奇怪地有一个方法
Iterator<T> iterator()
Run Code Online (Sandbox Code Playgroud)
所以你会期望它实现接口Iterable <T>,这需要完全这个方法,但事实并非如此.
当我想使用foreach循环遍历Stream时,我必须做类似的事情
public static Iterable<T> getIterable(Stream<T> s) {
return new Iterable<T> {
@Override
public Iterator<T> iterator() {
return s.iterator();
}
};
}
for (T element : getIterable(s)) { ... }
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么吗?
在Java 8中,Stream
该类没有任何方法来包装Iterable
.
相反,我Spliterator
从这里Iterable
获得了,然后Stream
从StreamSupport
这样获得一个:
boolean parallel = true;
StreamSupport.stream(spliterator(), parallel)
.filter(Row::isEmpty)
.collect(Collectors.toList())
.forEach(this::deleteRow);
Run Code Online (Sandbox Code Playgroud)
是否有产生的一些其他的方式Stream
上的操作Iterable
,我很想念?
Spliterator
Java 8中的类有什么好的用例场景?
为了防止实现细节泄漏,而不是返回,例如,Collection<MyCoolObject>
可以实现Iterable<MyCoolObject>
,然后需要Iterator<T>
从Iterable
接口实现.因此,无论如何管理内部数据结构,对元素的访问都是通过Iterator
.
使用Java 8,可能希望添加Stream<MyCoolObject> stream()
到MyCoolObject
.(另请参阅:Java 8 Lambdasstream
一书中支持的建议).虽然添加方法并不困难(我确实阅读了关于为什么Iterable不提供流的问题),但Java似乎没有添加一个接口来反映这个想法.(好吧,可能因为使用CORBA的东西而存在一个不同的名称).Streamable<T>
Iterable<T>
Streamable
我想,我也跟着为什么加入应答Stream
到Iterable
了可能存在问题,但我不明白为什么一个Streaming<T>
已经不能提供的接口.例如,Collections
可以实现Streaming<T>
接口,并且可以使人们可以期待stream()
方法的其他对象更清楚.
基于对上述引用问题的答案,可以Stream
从Iterable
通过获得
Stream s = StreamSupport.stream(iter.spliterator(), false);
Run Code Online (Sandbox Code Playgroud)
但这看起来似乎很多工作,MyObject
可能只想实现stream()
允许对象的用户这样做
myObject.stream().filter(...).collect(...)
Run Code Online (Sandbox Code Playgroud)
没有来自迭代器的干预转换.
缺少流媒体功能对象的接口是否有原因?有没有比仅仅stream()
在MyCoolObject上实现并让某人查看Javadoc以便他们知道它有stream()
方法更好的方法?
或者,很可能,我是否误解了Stream的方法?
(另外,我stream()
在CoolObject中实现,但后来忘记实现parallelStream()
,这可以通过使用接口来缓解).
假设您想要流式迭代器的元素; 让我们使用一个具体的例子Scanner
来实现Iterator<String>
.
给出一个Iterator
,说:
// Scanner implements Iterator<String>
Iterator<String> scanner = new Scanner(System.in);
Run Code Online (Sandbox Code Playgroud)
从中创建的选项Stream<String>
很笨重:
StreamSupport.stream(
Spliterators.spliteratorUnknownSize(scanner, Spliterator.ORDERED), false);
Run Code Online (Sandbox Code Playgroud)
或稍微简洁,但迟钝:
StreamSupport.stream(
((Iterable<String>) () -> new Scanner(System.in)).spliterator(), false);
Run Code Online (Sandbox Code Playgroud)
在JDK中的某个地方是否有一个返回Stream<T>
给定的工厂方法Iterator<T>
?
在C#的LINQ,GroupBy
返回IEnumerable
的IGrouping
项目,而这又是一个IEnumerable
所选择的值的类型的项目。这是一个例子:
var namesAndScores = new Dictionary<string, int>> {
["David"] = 90,
["Jane"] = 91,
["Bill"] = 90,
["Tina"] = 89)
};
var IEnumerable<IGrouping<int, string>> namesGroupedByScore =
namesAndScores
.GroupBy(
kvp => kvp.Value,
kvp => kvp.Key
);
// Result:
// 90 : { David, Bill }
// 91 : { Jane }
// 89 : { Tina }
Run Code Online (Sandbox Code Playgroud)
具体来说,请注意,每个IGrouping<int, string>
都是IEnumerable<string>
和不是List<string>
。(它也有一个.Key
属性。)
该GroupBy
显然有但是完全列举输入项目,才可以发出一个分组,因为它发出IEnumerable<string>
,而不是一个 …
java ×8
java-8 ×7
java-stream ×6
iterable ×4
iterator ×3
spliterator ×2
collectors ×1
grouping ×1