如何使用拆分器修改集合的元素
How to modify collection's elements with a spliterator
经过大量搜索,我发现 Spliterator
唯一支持的操作是从 Collection
读取元素。
谁能告诉我 Spliterator
支持的 CRUD 中的另一个操作。我尝试使用 Spliterator
修改 Collection
中的元素,但没有成功:
Set<Integer> set = new TreeSet<>();
set.add(2);
set.add(3);
set.add(5);
set.add(6);
Spliterator<Integer> si = set.spliterator();
Spliterator<Integer> sa = si.trySplit();
while(sa.tryAdvance(e -> e= ++e));
System.out.println("original iterator");
while(si.tryAdvance(e-> e = ++e));
System.out.println(set.toString());
Spliterator
cannot modify an underlying Collection
, mainly because Spliterator
(unlike Iterator
) 不是严格的 Collection
绑定接口。
Iterator
的定义(来自Iterator
's JavaDoc):
An iterator over a collection. [...]
Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
Spliterator
的定义(来自Spliterator
's JavaDoc):
An object for traversing and partitioning elements of a source. The source of elements covered by a Spliterator
could be, for example, an array, a Collection
, an IO channel, or a generator function.
编辑:我刚刚阅读了您发布的代码。在此代码中,您尝试在 Spliterator
调用中改变不可变的 Integer
实例。在这种情况下,Iterator
和 Spliterator
都不起作用,因为元素是不可变的。
使用 Stream
(or an IntStream
) for this, together with a map()
followed by collect()
.
已接受的答案提到的问题是 Integer
对象是不可变的,因此通过其迭代器或拆分器使用您的集合都不起作用,因为您无法修改整数实例 就地。但是,如果您的对象被认为是可变的,您可以通过 Iterator#next
或在 Spliterator#tryAdvance
的使用者中获取它们并将它们修改为常规可变对象(例如:通过暴露的 setter)。
作为解决方案,您可以流式传输您的集合,将每个整数实例映射到具有所需更改的新整数实例,从那里您可以将它们收集回新的 TreeSet<Integer>
。
final Set<Integer> newSet = set.stream()
.map(number -> number + 1)
.collect(Collectors.toCollection(TreeSet::new));
经过大量搜索,我发现 Spliterator
唯一支持的操作是从 Collection
读取元素。
谁能告诉我 Spliterator
支持的 CRUD 中的另一个操作。我尝试使用 Spliterator
修改 Collection
中的元素,但没有成功:
Set<Integer> set = new TreeSet<>();
set.add(2);
set.add(3);
set.add(5);
set.add(6);
Spliterator<Integer> si = set.spliterator();
Spliterator<Integer> sa = si.trySplit();
while(sa.tryAdvance(e -> e= ++e));
System.out.println("original iterator");
while(si.tryAdvance(e-> e = ++e));
System.out.println(set.toString());
Spliterator
cannot modify an underlying Collection
, mainly because Spliterator
(unlike Iterator
) 不是严格的 Collection
绑定接口。
Iterator
的定义(来自Iterator
's JavaDoc):
An iterator over a collection. [...]
Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
Spliterator
的定义(来自Spliterator
's JavaDoc):
An object for traversing and partitioning elements of a source. The source of elements covered by a
Spliterator
could be, for example, an array, aCollection
, an IO channel, or a generator function.
编辑:我刚刚阅读了您发布的代码。在此代码中,您尝试在 Spliterator
调用中改变不可变的 Integer
实例。在这种情况下,Iterator
和 Spliterator
都不起作用,因为元素是不可变的。
使用 Stream
(or an IntStream
) for this, together with a map()
followed by collect()
.
已接受的答案提到的问题是 Integer
对象是不可变的,因此通过其迭代器或拆分器使用您的集合都不起作用,因为您无法修改整数实例 就地。但是,如果您的对象被认为是可变的,您可以通过 Iterator#next
或在 Spliterator#tryAdvance
的使用者中获取它们并将它们修改为常规可变对象(例如:通过暴露的 setter)。
作为解决方案,您可以流式传输您的集合,将每个整数实例映射到具有所需更改的新整数实例,从那里您可以将它们收集回新的 TreeSet<Integer>
。
final Set<Integer> newSet = set.stream()
.map(number -> number + 1)
.collect(Collectors.toCollection(TreeSet::new));