Метод не возвращает то же самое, когда вызывается для того же объекта
Название сбивает с толку, но я понятия не имел, как описать это иначе. Я создаю объекты Linked List of Cars, и все хорошо, я печатаю список, вызывая мой метод getElement. Если это сделать, скажем, корвет, так System.out.print(corvette.getElement);
просто отображает corvette
как я этого хочу. Но если я сделаю то же самое с моим traverse
метод, когда corvette
находится в списке, он выплевывает linklist.Cars@5f531aca
, Код ниже.
public class LinkList <E>
{
private Cars<E> head;
private Cars<E> tail;
private static int length;
public int getLength()
{
return length;
}
public LinkList()
{
tail = new Cars();
head = new Cars(null, tail);
length = 0;
}
public void traverse()
{
Cars<E> cursor = head.getSuccessor();
while(cursor != tail)
{
System.out.println(cursor.getElement());
cursor = cursor.getSuccessor();
}
}
public Cars<E> find(int pos)
{
if(pos < 0 || pos >= this.length)
{
throw new IndexOutOfBoundsException();
}
Cars<E> cursor = head.getSuccessor();
for(int index = 0; index < pos; ++index)
{
cursor = cursor.getSuccessor();
}
return cursor;
}
public Cars<E> find(E element)
{
Cars<E> cursor = head.getSuccessor();
while(cursor != tail)
{
if(!cursor.getElement().equals(element))
cursor = cursor.getSuccessor();
else return cursor;
}
return null;
}
public void addAtHead(E element)
{
Cars<E> newNode = new Cars<>(element, null);
newNode.setSuccessor(head.getSuccessor());
head.setSuccessor(newNode);
++length;
}
public void insert(E element, int pos)
{
if(pos < 0 || pos > this.length)
{
throw new IndexOutOfBoundsException();
}
if(pos == 0)
{
addAtHead(element);
}
else if(pos == length)
{
addAtTail(element);
}
else
{
Cars<E> newNode = new Cars<>(element, null);
Cars<E> prevNode = find(pos - 1);
newNode.setSuccessor(prevNode.getSuccessor());
prevNode.setSuccessor(newNode);
++length;
}
}
public void addAtTail(E element)
{
Cars<E> newNode = new Cars<>(element, null);
if(length > 0)
{
Cars<E> lastNode = find(this.length - 1);
newNode.setSuccessor(lastNode.getSuccessor());
lastNode.setSuccessor(newNode);
}
else
{
newNode.setSuccessor(head.getSuccessor());
head.setSuccessor(newNode);
}
++length;
}
public E delete(int pos)
{
if(pos < 0 || pos >= this.length)
{
throw new IndexOutOfBoundsException();
}
Cars<E> prevNode;
if(pos == 0)
{
prevNode = head;
}
else
{
prevNode = find(pos - 1);
}
Cars<E> poorUnfortunateSoul = prevNode.getSuccessor();
prevNode.setSuccessor(poorUnfortunateSoul.getSuccessor());
poorUnfortunateSoul.setSuccessor(null);
--length;
return poorUnfortunateSoul.getElement();
}
public static void main(String[] args)
{
Cars corvette = new Cars("corvette", null);
Cars pinto = new Cars("pinto", null);
Cars mustang = new Cars("mustang", null);
Cars bmw = new Cars("bmw", null);
Cars elio = new Cars("elio", null);
LinkList list = new LinkList();
list.addAtTail(corvette);
list.addAtTail(pinto);
list.addAtTail(mustang);
list.addAtTail(bmw);
list.addAtTail(elio);
System.out.println(corvette.getElement());
list.traverse();
следующий мой класс автомобилей.
public class Cars <E>
{
private E element;
private Cars successor;
public Cars()
{
this.element = null;
this.successor = null;
}
public Cars(E element, Cars<E> node)
{
this.element = element;
this.successor = node;
}
public E getElement()
{
return this.element;
}
public void setElement(E element)
{
this.element = element;
}
public Cars<E> getSuccessor()
{
return this.successor;
}
public void setSuccessor(Cars successor)
{
this.successor = successor;
}
}
По сути, метод испытаний выводит:
corvette
linklist.Cars@5f531aca
linklist.Cars@4903f4aa
linklist.Cars@22b3ea59
linklist.Cars@51de8adb
linklist.Cars@696e59da
И я понятия не имею, почему, когда они оба просто печатают getElement
метод. Есть идеи?
РЕДАКТИРОВАТЬ: Я понимаю, что это глупый способ делать вещи, но это то, что это (назначение). Что я действительно хочу знать, так это почему corvette.getElement()
а также cursor.getElement
в traverse
метод, предусматривающий разные вещи, когда они (из того, что я знаю) должны выполнять одно и то же действие.
2 ответа
public void addAtTail(E element)
Это должно занять E
, В вашем случае строка типа "corvette"
,
Но вы вызываете метод с Cars<E>
,
Cars corvette = new Cars("corvette", null);
list.addAtTail(corvette);
В результате ваши элементы списка обернуты дважды.
Cars<E> newNode = new Cars<>(element, null);
Разве вы не получаете некоторые предупреждения типа?
Вы должны использовать ваши общие типы:
Cars<String> corvette = new Cars("corvette", null);
Затем компилятор обнаружит несоответствие типов и откажется компилировать этот код.
Ваша ошибка заключается в том, что ваш addAtTail
метод принимает E
в качестве параметра, а не Car
как вы предоставляете. Вы должны просто позвонить addAtTail("corvette")
, Этой проблемы можно было бы избежать, если бы вы на самом деле использовали универсальный класс - вот для чего он нужен. Вместо LinkList list = new LinkList();
использовать LinkList<String> list = new LinkList<String>();
(поскольку в этом случае вы помещаете строки в список), и аналогично Cars
должно быть Cars<String>
, Это предотвратит случайное добавление неверного типа в список, как это происходит в этом случае.
РЕДАКТИРОВАТЬ: Кроме того, ваш код, кажется, сбивает с толку, что именно автомобиль и что является элементом списка. Ваш Cars
класс на самом деле, кажется, не представляет автомобиль. Для объекта авто не нужно знать, какая машина идет после него в списке. Вы, вероятно, должны переименовать Cars
класс что-то вроде ListNode
потому что каждый экземпляр этого представляет один узел списка. Этот узел сам по себе не является автомобилем, но он должен содержать автомобиль - вот для чего предназначено поле элемента. Cars
тогда класс имел бы только информацию об автомобиле. Тогда у вас будет что-то вроде:
LinkList<Car> list = new LinkList<Car>;
list.addAtTail(new Car("corvette"));
addAtTail
Метод будет затем создать ListNode<Car>
объект, содержащий автомобиль, который вы только что создали, и добавьте его в список.