1

经过大量搜索,我发现唯一支持的操作Spliterator是从 READ 元素中读取元素Collection

有人可以告诉我 CRUD 中可以支持的另一个操作Spliterator。我尝试Collection使用 a修改元素,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());
4

2 回答 2

2

Spliterator不能修改底层Collection,主要是因为Spliterator(不像Iterator)不是严格Collection绑定的接口。

Iterator(来自Iterator's JavaDoc)的定义:

集合上的迭代器。[...]

迭代器允许调用者在具有明确定义的语义的迭代期间从底层集合中删除元素。

Spliterator(来自Spliterator's JavaDoc)的定义:

用于遍历和划分源元素的对象。a 所覆盖的元素的来源Spliterator可以是,例如,数组、a Collection、IO 通道或生成器函数。


编辑:我刚刚阅读了您发布的代码。在这段代码中,您尝试在调用中改变一个不可变的Integer实例。Spliterator在这种情况下,既不IteratorSpliterator不能工作,因为元素是不可变的。

为此使用 a Stream(或 an IntStream),map()然后使用 a collect()

于 2018-07-26T05:55:39.220 回答
1

接受的答案提到的问题是Integer对象是不可变的,因此通过其迭代器或拆分器使用您的集合都不会起作用,因为您不能就地修改整数实例。但是,如果您的对象被认为是可变的,您可以通过Iterator#next或在消费者中获取它们并将它们Spliterator#tryAdvance修改为常规可变对象(例如:通过公开的设置器)。

作为一种变通解决方案,您可以流式传输您的集合,将每个整数实例映射到具有所需更改的新整数实例,从那里您可以将它们收集回一个新的TreeSet<Integer>.

final Set<Integer> newSet = set.stream()
    .map(number -> number + 1)
    .collect(Collectors.toCollection(TreeSet::new));
于 2018-07-26T09:52:11.590 回答