如何在java中解决这个不合适的类型错误?

时间:2017-09-08 14:50:59

标签: java generics types

当我尝试将linkedList中的last或first元素的值赋给新Item时出错,Item result = lastItem.previousNode.value;它表示不合适的类型,必需的Item,找到了java.lang.Object。我做错了什么,我该如何解决这个问题?谢谢。

这是我的代码:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Deque<Item> implements Iterable<Item> {

private int size;
private node<Item> firstItem  = new node<>();
private node<Item> lastItem = new node<>();

public Deque() {
    firstItem.previousNode = null;
    firstItem.nextNode = lastItem;
    lastItem.previousNode = firstItem;
    lastItem.nextNode = null;
    size = 0;
}                          // construct an empty deque

public boolean isEmpty() { return firstItem.nextNode == lastItem;}                // is the deque empty?

public int size() { return size;}                        // return the number of items on the deque

public void addFirst(Item item) {
    if(item == null){
        throw new NullPointerException("cant add null to deque");
    }

    if(firstItem.nextNode == lastItem){
        node nextItem = new node();
        nextItem.value = item;
        firstItem.nextNode = nextItem;
        nextItem.previousNode = firstItem;
        lastItem.previousNode = nextItem;
        nextItem.nextNode = lastItem;
    }
    else{
        node nextItem = new node();
        nextItem.value = item;
        firstItem.nextNode.previousNode = nextItem;
        nextItem.previousNode = firstItem;
        nextItem.nextNode = firstItem.nextNode;
        firstItem.nextNode = nextItem;
    }
    size++;
}         // add the item to the front

public void addLast(Item item) {
    if(item == null){
        throw new NullPointerException("cant add null to deque");
    }

    if(lastItem.previousNode == firstItem){
        node nextItem = new node();
        nextItem.value = item;
        firstItem.nextNode = nextItem;
        nextItem.previousNode = firstItem;
        lastItem.previousNode = nextItem;
        nextItem.nextNode = lastItem;
    }
    else {
        node nextItem = new node();
        nextItem.value = item;
        nextItem.previousNode = lastItem.previousNode;
        lastItem.previousNode = nextItem;
        nextItem.nextNode = lastItem;
        lastItem.previousNode.nextNode = nextItem;
    }
    size++;
}          // add the item to the end

public Item removeFirst(){
    if (firstItem.nextNode == lastItem) {
        throw new NoSuchElementException("Client tries to remove an Item from empty deque.");
    }
    node result = firstItem.nextNode;
    firstItem.nextNode = firstItem.nextNode.nextNode;
    firstItem.nextNode.nextNode.previousNode = firstItem;
    size--;
    return result.value;
}                // remove and return the item from the front

public Item removeLast() {
    if(lastItem.previousNode == firstItem){
        throw new NoSuchElementException("Client tries to remove an Item from empty deque.");
    }
    Item result = lastItem.previousNode.value;
    lastItem.previousNode = lastItem.previousNode.previousNode;
    lastItem.previousNode.nextNode = lastItem;
    size--;
    return result;
}                // remove and return the item from the end

public Iterator<Item> iterator() {
    return new dequeIterator();
}        // return an iterator over items in order from front to end

    private class dequeIterator implements Iterator<Item>{
        private node<Item> nextNode = firstItem;

        @Override
        public boolean hasNext(){
            return nextNode.nextNode != lastItem;
        }

        @Override
        public Item next() {
            if (!hasNext()) {
                throw new NoSuchElementException("No next element available. Reached end of deque.");
            }

            Item returnValue = nextNode.value;
            nextNode = nextNode.nextNode;
            return returnValue;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Remove is not supported");
        }
    }


    public static void main(String[] args){}   // unit testing (optional)

    private class node<Item>{
        private Item value;
        private node previousNode;
        private node nextNode;
    }
}

1 个答案:

答案 0 :(得分:0)

您的node课程正在重新定义您打算使用的通用课程。不要这样做。只需使用Item内的通用node来声明值即可。您无需声明node<Item>。所以,你的node课程就变成了这个:

private class node {
    private Item value;
    private node previousNode;
    private node nextNode;
}

由于重新声明了通用Item,因此无法将node.Item转换为Deque.Item。这就是你错误的原因。

此外,在实例化node个对象时,您需要删除所有泛型:

例如,

node<Item> firstItem  = new node<>();

将成为:

node firstItem  = new node();

这将是您的整个Deque课程:

public class Deque<Item> implements Iterable<Item> {

    private int size;
    private node firstItem = new node();
    private node lastItem = new node();

    public Deque() {
        firstItem.previousNode = null;
        firstItem.nextNode = lastItem;
        lastItem.previousNode = firstItem;
        lastItem.nextNode = null;
        size = 0;
    } // construct an empty deque

    public boolean isEmpty() {
        return firstItem.nextNode == lastItem;
    } // is the deque empty?

    public int size() {
        return size;
    } // return the number of items on the deque

    public void addFirst(Item item) {
        if (item == null) {
            throw new NullPointerException("cant add null to deque");
        }

        if (firstItem.nextNode == lastItem) {
            node nextItem = new node();
            nextItem.value = item;
            firstItem.nextNode = nextItem;
            nextItem.previousNode = firstItem;
            lastItem.previousNode = nextItem;
            nextItem.nextNode = lastItem;
        } else {
            node nextItem = new node();
            nextItem.value = item;
            firstItem.nextNode.previousNode = nextItem;
            nextItem.previousNode = firstItem;
            nextItem.nextNode = firstItem.nextNode;
            firstItem.nextNode = nextItem;
        }
        size++;
    } // add the item to the front

    public void addLast(Item item) {
        if (item == null) {
            throw new NullPointerException("cant add null to deque");
        }

        if (lastItem.previousNode == firstItem) {
            node nextItem = new node();
            nextItem.value = item;
            firstItem.nextNode = nextItem;
            nextItem.previousNode = firstItem;
            lastItem.previousNode = nextItem;
            nextItem.nextNode = lastItem;
        } else {
            node nextItem = new node();
            nextItem.value = item;
            nextItem.previousNode = lastItem.previousNode;
            lastItem.previousNode = nextItem;
            nextItem.nextNode = lastItem;
            lastItem.previousNode.nextNode = nextItem;
        }
        size++;
    } // add the item to the end

    public Item removeFirst() {
        if (firstItem.nextNode == lastItem) {
            throw new NoSuchElementException("Client tries to remove an Item from empty deque.");
        }
        node result = firstItem.nextNode;
        firstItem.nextNode = firstItem.nextNode.nextNode;
        firstItem.nextNode.nextNode.previousNode = firstItem;
        size--;
        return result.value;
    } // remove and return the item from the front

    public Item removeLast() {
        if (lastItem.previousNode == firstItem) {
            throw new NoSuchElementException("Client tries to remove an Item from empty deque.");
        }
        Item result = lastItem.previousNode.value;
        lastItem.previousNode = lastItem.previousNode.previousNode;
        lastItem.previousNode.nextNode = lastItem;
        size--;
        return result;
    } // remove and return the item from the end

    public Iterator<Item> iterator() {
        return new dequeIterator();
    } // return an iterator over items in order from front to end

    private class dequeIterator implements Iterator<Item> {
        private node nextNode = firstItem;

        @Override
        public boolean hasNext() {
            return nextNode.nextNode != lastItem;
        }

        @Override
        public Item next() {
            if (!hasNext()) {
                throw new NoSuchElementException("No next element available. Reached end of deque.");
            }

            Item returnValue = nextNode.value;
            nextNode = nextNode.nextNode;
            return returnValue;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Remove is not supported");
        }
    }

    public static void main(String[] args) {
    } // unit testing (optional)

    private class node {
        private Item value;
        private node previousNode;
        private node nextNode;
    }

}

PS:我建议使用单个字母(如E,K,I等)来定义泛型而不是像Item这样的名称。它很容易被误解为一个阶级。

希望这有帮助!