Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.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_Stack_Queue_Immutability - Fatal编程技术网

Java 创建不可变队列的问题

Java 创建不可变队列的问题,java,stack,queue,immutability,Java,Stack,Queue,Immutability,我使用下面的代码创建一个不可变队列 import java.util.NoSuchElementException; import java.util.Queue; public class ImmutableQueue<E> { //Two stacks are used. One is to add items to the queue(enqueue) and //other is to remove them(dequeue) private

我使用下面的代码创建一个不可变队列

import java.util.NoSuchElementException;
import java.util.Queue;

public class ImmutableQueue<E> {

    //Two stacks are used. One is to add items to the queue(enqueue) and 
    //other is to remove them(dequeue)


    private ImmutableQueue(ReversableStack<E> order, ReversableStack<E> reverse) {
        this.order = order;
        this.reverse = reverse;
    }

    //initially both stacks are empty
    public ImmutableQueue() {
        this.order = ReversableStack.emptyStack();
        this.reverse = ReversableStack.emptyStack();
    }

    public ImmutableQueue<E> enqueue(E e) {
        if (null == e)
            throw new IllegalArgumentException();
        return new ImmutableQueue<E>(this.order.push(e), this.reverse);
    }

    public ImmutableQueue<E> dequeue() {
        if (this.isEmpty())
            throw new NoSuchElementException();
        if (!this.reverse.isEmpty()) {
            return new ImmutableQueue<E>(this.order, this.reverse.tail);
        } else {

            return new ImmutableQueue<E>(ReversableStack.emptyStack(),
                    this.order.getReverseStack().tail);
        }
    }




    private static class ReversableStack<E> {
        private E head; //top of original stack
        private ReversableStack<E> tail; //top of reversed stack
        private int size;

        //initializing stack parameters
        private ReversableStack(E obj, ReversableStack<E> tail) {
            this.head = obj;
            this.tail = tail;
            this.size = tail.size + 1;
        }

        //returns a new empty stack
        public static ReversableStack emptyStack() {
            return new ReversableStack();
        }

        private ReversableStack() {
            this.head = null;
            this.tail = null;
            this.size = 0;
        }

        //Reverses the original stack
        public ReversableStack<E> getReverseStack() {
            ReversableStack<E> stack = new ReversableStack<E>();
            ReversableStack<E> tail = this;
            while (!tail.isEmpty()) {
                stack = stack.push(tail.head);
                tail = tail.tail;
            }
            return stack;
        }

        public boolean isEmpty() {
            return this.size == 0;
        }

        public ReversableStack<E> push(E obj) {
            return new ReversableStack<E>(obj, this);
        }
    }

    private ReversableStack<E> order;

    private ReversableStack<E> reverse;



    private void normaliseQueue() {
        this.reverse = this.order.getReverseStack();
        this.order = ReversableStack.emptyStack();
    }

    public E peek() {
        if (this.isEmpty())
            throw new NoSuchElementException();
        if (this.reverse.isEmpty())
            normaliseQueue();
        return this.reverse.head;
    }

    public boolean isEmpty() {
        return size() == 0;
    }

    //returns the number of items currently in the queue
    public int size() {
        return this.order.size + this.reverse.size;
    }

    public static void main(String[] args)
    {
        ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
        newQueue.enqueue(5);
        newQueue.enqueue(10);
        newQueue.enqueue(15);
        int x = newQueue.size();
        //ImmutableQueue<Integer> x = newQueue.dequeue();
        System.out.println(x);

    }

}
import java.util.NoSuchElementException;
导入java.util.Queue;
公共类不可变队列{
//使用两个堆栈。一个是将项目添加到队列(排队)中,另一个是
//另一种是移除它们(出列)
私有不可变队列(ReversableStack顺序,ReversableStack反向){
这个。顺序=顺序;
这个。反向=反向;
}
//最初,两个堆栈都是空的
公共不可变队列(){
this.order=ReversableStack.emptyStack();
this.reverse=ReversableStack.emptyStack();
}
公共不可变队列排队(E){
如果(null==e)
抛出新的IllegalArgumentException();
返回新的不可变队列(this.order.push(e),this.reverse);
}
公共不可变队列出列(){
if(this.isEmpty())
抛出新的NoTouchElementException();
如果(!this.reverse.isEmpty()){
返回新的不可变队列(this.order、this.reverse.tail);
}否则{
返回新的ImmutableQueue(ReversableStack.emptyStack(),
这个.order.getReverseStack().tail);
}
}
私有静态类ReversableStack{
private E head;//原始堆栈的顶部
private ReversableStack tail;//反转堆栈的顶部
私有整数大小;
//初始化堆栈参数
私有可逆堆栈(E obj,可逆堆栈尾部){
this.head=obj;
this.tail=tail;
this.size=tail.size+1;
}
//返回一个新的空堆栈
公共静态可逆堆栈emptyStack(){
返回新的ReversableStack();
}
私有可逆堆栈(){
this.head=null;
this.tail=null;
此值为0.size=0;
}
//反转原始堆栈
public ReversableStack getReverseStack(){
ReversableStack=新的ReversableStack();
可逆堆栈尾=此;
而(!tail.isEmpty()){
stack=stack.push(尾部、头部);
tail=tail.tail;
}
返回栈;
}
公共布尔值为空(){
返回this.size==0;
}
公共可逆堆栈推送(E obj){
返回新的可逆堆栈(obj,this);
}
}
私有可逆堆栈顺序;
私有可逆堆栈反向;
私有void normaliseQueue(){
this.reverse=this.order.getReverseStack();
this.order=ReversableStack.emptyStack();
}
公共E peek(){
if(this.isEmpty())
抛出新的NoTouchElementException();
if(this.reverse.isEmpty())
normaliseQueue();
返回此.reverse.head;
}
公共布尔值为空(){
返回大小()==0;
}
//返回队列中当前的项目数
公共整数大小(){
返回this.order.size+this.reverse.size;
}
公共静态void main(字符串[]args)
{
ImmutableQueue newQueue=新的ImmutableQueue();
排队(5);
排队(10);
排队(15);
int x=newQueue.size();
//ImmutableQueue x=newQueue.dequeue();
系统输出println(x);
}
}
但是,每当我尝试出列时,我都会得到一个无趣的例外。此外,newQueue.size函数还返回0。 我做错了什么?
谢谢

您缺少新的
不可变队列
参考

因为
enqueue()
方法返回
ImmutableQueue

public ImmutableQueue<E> enqueue(E e) {
    if (null == e)
        throw new IllegalArgumentException();
    return new ImmutableQueue<E>(this.order.push(e), this.reverse);
}

您将看到尺寸将发生变化

,谢谢,这非常有效。你能给我一个关于如何在这种情况下调用dequeue的示例行吗?newQueue=newQueue.dequeue();接得好。看起来OP在主方法中将不可变对象视为可变对象。是的。。。这违背了目的。。。这就像做
String s=“hello”
然后调用
s.toUpperCase()
并认为这将影响
String s
您不能在ImmutableQueue对象上同时获取队列的新副本和您退出队列的值。。。。除非您返回的是一个新对象,该对象具有新的Immutablequeue对象和结果字段
public static void main(String[] args)
{
    ImmutableQueue<Integer> newQueue = new ImmutableQueue<Integer>();
    newQueue.enqueue(5);
    newQueue.enqueue(10);
    newQueue.enqueue(15);
    int x = newQueue.size();
    //ImmutableQueue<Integer> x = newQueue.dequeue();
    System.out.println(x);

}
newQueue = newQueue.enqueue(5);
int x = newQueue.size();
System.out.println(x);