Цикл
A for
состоит из четырех частей: выражение инициализации , выражение завершения , выражение приращения и корпус .
(Также есть цикл для каждого , который имеет другой синтаксис, но это не то, о чем мы здесь говорим.)
Итак, чтобы разобрать это на части:
- Выражение инициализации пусто (ничего до первого
;
)
- Выражение завершения равно
tmp != null && !(tmp.info.equals(el)
- Выражение приращения равно
pred = pred.next, tmp = tmp.next
- Тело также пусто (после закрывающего
)
выражения for
следующий оператор просто ;
На простом английском языке:
Пока tmp
не является null
, но tmp.info
не является нашим желаемым элементом el
, продолжайте перемещаться pred
и tmp
, чтобы указывать на элементы-преемники в связанном списке.
Условием завершения этого цикла является то, что либо tmp
равно null
(если el
вообще не был элементом списка), либо pred
указывает на узел до узел, который имеет el
в качестве значения, а tmp
указывает на узел, который имеет el
в качестве значения.
Обратите внимание, что этот код написан в очень кратком стиле. Этот стиль был распространен для низкоуровневого кода 20+ лет назад; в настоящее время, когда я вижу такой код, это заставляет меня думать, что он был написан старым таймером.
Я бы, вероятно, вместо этого написал бы такой же метод:
public void delete(Object item) {
if (head == null) {
// The list is empty; we have no work to do.
return;
}
if (head.info.equals(item)) {
// We're deleting the head of the list; just update our head reference.
head = head.next;
return;
}
SLLNode previous = head;
SLLNode current = head.next;
while (current != null) {
if (current.info.equals(item)) {
// Update the list to skip the current node, then we're done.
previous.next = current.next;
return;
}
// Move to the next node in the list.
previous = current;
current = current.next;
}
// If we reached this point, the item was not found in this list.
// There's nothing to do, so we're done anyway.
}