Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何防止迭代器列表的变异?_Java_Iterator_Immutability - Fatal编程技术网

Java 如何防止迭代器列表的变异?

Java 如何防止迭代器列表的变异?,java,iterator,immutability,Java,Iterator,Immutability,我希望避免其他人对迭代器测试的输入列表进行变异。我只希望其他人在测试的深层副本上运行 如何在Java中实现这一点 下面是一个例子,显示了突变对测试的影响。这两部分都在对输入进行排序。但是第二部分没有什么需要排序的,因为第一部分的变异将迭代器迭代到最后 您可以在此处联机运行以下示例: 导入java.util.*; 公共类不可变示例{ 公共静态void main(字符串[]args){ System.out.println(“按需排序”); List mutableTests=Arrays.as

我希望避免其他人对迭代器
测试的输入列表进行变异。我只希望其他人在
测试的深层副本上运行

如何在Java中实现这一点

下面是一个例子,显示了突变对
测试的影响。这两部分都在对输入进行排序。但是第二部分没有什么需要排序的,因为第一部分的变异将迭代器迭代到最后

您可以在此处联机运行以下示例:


导入java.util.*;
公共类不可变示例{
公共静态void main(字符串[]args){
System.out.println(“按需排序”);
List mutableTests=Arrays.asList(
Arrays.asList(1,2).iterator(),
Arrays.asList(0.iterator(),
Collections.emptyIterator()
);
列表测试=集合。不可修改列表(可变测试);
MergingIterator MergingIterator=新的MergingIterator(测试);
while(mergingIterator.hasNext()){
System.out.println(mergingIterator.next());
}
System.out.println(“一次排序”);
/*取消注释以下内容将看到相同的结果:*/
//tests=Arrays.asList(
//Arrays.asList(1,2).iterator(),
//Arrays.asList(0.iterator(),
//Collections.emptyIterator()
//        );
MergeKSortedIterators sol=新的MergeKSortedIterators();
Iterable result=sol.Mergeksortedirators(测试);
for(整数num:result){
系统输出打印项数(num);
}
}
}
类PeekingIterator实现了迭代器,可比较{
迭代器;
整型peek元素;
布尔偷看;
公共窥视迭代器(迭代器迭代器){
this.iterator=迭代器;
}
公共布尔hasNext(){
return haspeek | |迭代器.hasNext();
}
公共整数next(){
int-nextElem=haspeek?peek元素:迭代器.next();
haspeek=false;
返回NEXTLEM;
}
公共整数peek(){
peek元素=haspeek?peek元素:迭代器.next();
haspeek=true;
返回元素;
}
@凌驾
公共整数比较(PeekingIterator){
返回this.peek()-that.peek();
}
}
类MergingIterator实现了迭代器{
队列堆;
公共MergingIterator(列表迭代器){
//minHeap=newpriorityqueue((x,y)->x.peek().compareTo(y.peek());
minHeap=new PriorityQueue();
for(迭代器迭代器:迭代器){
if(iterator.hasNext()){
offer(新的PeekingIterator(迭代器));
}
}
}
公共布尔hasNext(){
return!minHeap.isEmpty();
}
公共整数next(){
PeekingIterator nextite=minHeap.poll();
整数next=nextIter.next();
if(nextIter.hasNext()){
minHeap.offer(nextIter);
}
下一步返回;
}
}
类mergeksortedirators{
公共Iterable mergeksortedirators(列表迭代器列表){
列表结果=新建ArrayList();
if(iteratorList.isEmpty()){
返回结果;
}
PriorityQueue pq=新的PriorityQueue();
for(迭代器迭代器:迭代器列表){
if(iterator.hasNext()){
添加(新的PeekingIterator(迭代器));
}
}
而(!pq.isEmpty()){
PeekingIterator curr=pq.poll();
//添加(curr.peek());
//无法将此项用作hasNext()对“HasPeek”的检查`
result.add(curr.next());
if(curr.hasNext()){
新增产品质量(当前);
}
}
返回结果;
}
}

这个问题似乎是基于一种误解。。。一两个

如何防止迭代器列表的变异

您需要区分列表的易变性和列表中项目的易变性。我想你实际上是在问后者。(因此,清单与问题并不真正相关。我们将看到。)

我希望避免其他人对迭代器测试的输入列表进行变异

同样,您似乎在询问列表,但我认为您实际上是想询问迭代器

我只希望其他人在测试的深层副本上运行

这意味着您希望迭代器是不可变的

问题是:

  • 迭代器是一个固有的有状态/可变对象。实际上,如果不改变迭代器对象,就无法实现
    next()

  • 迭代器
    对象通常不可深度复制。它们通常不支持
    clone()
    或公共构造函数,并且通常不实现
    Serializable
    。(事实上,如果它们是可序列化的,序列化/反序列化的语义就会有问题。)

因此,基本上,你所设想的不可变迭代器列表或(以某种方式)生成迭代器深度副本的列表是不实际的


你评论道:

所以
List tests=Collections.unmodifiableList(mutableTests)无法为
列表生成不可修改的列表

嗯,是的,它可以。但这并不能解决问题。您需要一个不可修改的迭代器列表,而不是一个不可修改的迭代器列表


可能的解决办法:

  • 您可以从迭代器的基本集合中为每个测试运行重新创建迭代器列表

  • 使用
    Iterable
    而不是
    Iterator
    。您正在使用的集合类型都实现了Iterable,第三个迭代器可以从空列表中创建

    List<Iterable<Integer>> tests = Arrays.asList(
            Arrays.asList(1, 2),
            Arrays.asList(0),
            Collections.emptyList()
    );
    
    // to use them ...
    
    for (Iterable<Integer> iterable : tests) {
        Iterator<Integer> iterator = iterable.iterator();
        // etc ...
    }
    
    List tests=Arrays.asList(
    数组。asList(1,2),
    数组。asList(0),
    
    List<Iterable<Integer>> tests = Arrays.asList(
            Arrays.asList(1, 2),
            Arrays.asList(0),
            Collections.emptyList()
    );
    
    // to use them ...
    
    for (Iterable<Integer> iterable : tests) {
        Iterator<Integer> iterator = iterable.iterator();
        // etc ...
    }