经过大量搜索,我发现Spliterator
支持的唯一操作是从Collection
读取元素。
有人可以告诉我有关Spliterator
支持的CRUD中的另一种操作。我尝试使用Collection
来修改Spliterator
中的元素,但是没有用:
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());
答案 0 :(得分:2)
Spliterator
无法修改基础的Collection
,主要是因为Spliterator
(与Iterator
不同)并不是严格受Collection
约束的接口。
Iterator
的定义(来自Iterator
's JavaDoc):
集合上的迭代器。 [...]
迭代器允许调用者在迭代过程中使用定义明确的语义从基础集合中删除元素。
Spliterator
的定义(来自Spliterator
's JavaDoc):
用于遍历和划分源元素的对象。
Spliterator
覆盖的元素来源可以是例如数组,Collection
,IO通道或生成器函数。
EDIT :我刚刚阅读了您发布的代码。在此代码中,您尝试在Integer
调用中对不可变的Spliterator
实例进行突变。在这种情况下,Iterator
和Spliterator
都不起作用,因为元素是不可变的。
答案 1 :(得分:1)
这里公认的答案提到的问题是Integer
对象是不可变的,因此不能通过其迭代器或拆分器使用集合,因为您不能就地修改整数实例 / em>。但是,如果您认为对象是可变的,则可以通过Iterator#next
或在Spliterator#tryAdvance
的使用者中获取它们,并将其修改为常规的可变对象(例如,通过公开的setter)。
作为解决方案,您可以流处理集合,将每个整数实例映射到具有所需更改的新整数实例,然后从那里将它们收集回到新的TreeSet<Integer>
中。
final Set<Integer> newSet = set.stream()
.map(number -> number + 1)
.collect(Collectors.toCollection(TreeSet::new));