У меня вопрос о том, как Linked List хранит данные и ссылается друг на друга.
public class LinkedList {
static class Node {
int data;
Node next;
// Constructor
Node(int d)
{
data = d;
next = null;
}
}
public static void main (String[] args) {
Node first = new Node(1);
Node second = new Node(2);
Node third = new Node(3);
Node fourth = new Node(4);
Node fifth = new Node(5);
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
second = fourth;
System.out.println(second.data + "is fourth");
while (first != null) {
System.out.println(first.data);
first = first.next;
}
}
}
Этот код распечатывает
4 is fourth
1
2
3
4
5
Тем не менее, я думал, что это должно быть
4 is fourth
1
4
5
Потому что я изменил «второе» значение на «четвертое» значение
Кто-нибудь может объяснить, что здесь происходит?
Вы поменяли вторую на четвертую, а не вторую на четвертую.
Спасибо за ответ, однако я не пытаюсь получить желаемый результат, но хочу знать, почему он все еще выводит «4 12345», когда выводится «second.data» 4. Не могли бы вы уточнить эту часть?
Важно понимать, что происходит, когда вы вызываете метод или создаете новую переменную в памяти, чтобы понять это поведение. По сути, в памяти есть две части, где данные хранятся для чего-то подобного — стек и куча. Стек хранит статическую информацию и имеет фиксированный размер, в то время как куча может хранить более сложные данные (например, объекты) и не имеет определенных ограничений по размеру, кроме объема доступной памяти.
Когда вы создаете экземпляр объекта в Java, сам объект (значения и свойства) определяется и сохраняется в куче, тогда как ссылка на данные или адрес памяти объекта в куче сохраняется в переменной на куча. Вот почему, когда вы делаете что-то вроде
ExampleObject o = new ExampleObject();
System.out.println(o);
печатает что-то вроде ExampleObject@fa243dsf
Этот вывод не является самим объектом, который может иметь определенные свойства, которые вы определили, а выводит ссылку на сам объект. Когда вы делаете что-то вроде o.exampleProperty
, вы разыменовываете объект, то есть вы говорите Java перейти к адресу памяти объекта и получить значение exampleProperty
.
Теперь, чтобы вернуться к вашему вопросу, то же самое происходит со свойством next
для каждого Node
, оно хранит не сам объект, а ссылку на этот объект. Давайте представим, что это адреса памяти для каждого из созданных вами экземпляров Node
(просто для примера, это не точные места, где они хранятся Java на вашем компьютере, и не правильные адреса памяти):
first has an address of 111
second has an address of 222
third has an address of 333
fourth has an address of 444
fifth has an address of 555
Теперь ваш LL выглядит так после присвоения следующих значений:
first.next = Node@222
second.next = Node@333
third.next = Node@444
fourth.next = Node@555
fifth.next = null
Теперь, когда Java достигает строки second = fourth
, вы изменили не сами данные объекта, а только адрес памяти, на который указывает переменная second
. Под этим я подразумеваю, что second
теперь указывает на адрес 444
, и если вы запустите System.out.println(second);
, вы увидите, что Node@444
выводится на консоль, однако вы не изменили исходный объект, на который ссылается second
, и не изменили значения LinkedList
. Это означает, что значение по адресу памяти 222
не изменилось, и, поскольку first.next
указывает на Node@222
, значение Node
, созданное и сохраненное по адресу 222
, такое же, как оно было изначально. Вот почему, когда вы печатаете second.data
в конце, вы получаете то же значение, что и fourth.data
, но почему само LinkedList
не изменилось до того, на что вы думали, что оно изменится. Если это объяснение все еще не очень ясно, я предлагаю вам изучить переменные, хранящие/передающие данные по ссылке и по значению, поскольку это концепция, которая описывает поведение, которое вы видите, по сравнению с тем, что вы ожидали.
Привет, Сал, я действительно ценю твой ответ! Теперь стало так ясно! Большое спасибо ! оцените это снова!
вы не меняете никаких значений. второй ссылается на четвертый, который содержит значение нового узла (4). Вам нужно написать first.next = четвертый, чтобы получить желаемый результат