#java #conditional-statements
Вопрос:
Я довольно новичок в java и практиковал здесь какой-то литкод: https://leetcode.com/problems/same-tree/
Мое решение этого вопроса было:
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null amp;amp; q == null){
return true;
}
return (p.val == q.val)amp;amp;(p != null amp;amp; q != null)amp;amp;
isSameTree(p.left, q.left)amp;amp;
isSameTree(p.right, q.right);
}
}
и я просто не мог заставить его работать с ним, что привело к ошибке нулевого указателя. Но тогда простое переключение условного:
return (p != null amp;amp; q != null)amp;amp;(p.val == q.val)amp;amp;
isSameTree(p.left, q.left)amp;amp;
isSameTree(p.right, q.right);
и вдруг это срабатывает. Понятия не имею, почему. Я думал, что amp;amp; является логическим оператором и, поэтому A и B-это то же самое, что B и A … что происходит?
Ответ №1:
В большинстве языков программирования выражения вычисляются слева направо. В вашем предыдущем подходе p.val
это может привести к исключению NullPointerException, когда p
значение равно null. Чтобы избежать этого, вы всегда должны проверять условия null перед в ваших выражениях И/ИЛИ. Что именно вы и сделали (я думаю, не осознавая этого.).
Ответ №2:
В математике, булевой алгебре или чем-то еще оператор И обладает ассоциативными и коммутативными свойствами, так что с математической точки зрения-нет.
Однако большинство языков программирования используют ленивую оценку для своих логических и операторов. Если первый операнд есть false
, а оператор есть amp;amp;
, то зачем утруждать себя оценкой второго операнда, если вы знаете, что он просто вернет false?
Используя это, вы можете избежать ошибок (подобных той, которую вы опубликовали), изменив порядок операндов.
Например, если вы хотите избежать object is undefined
ошибки при попытке доступа к элементам объекта, вы можете это сделать if(object != undefined amp;amp; object.isExample)
. Если object
не определено, то оно знает, что это выражение является ложным, и завершает там.
Ответ №3:
Оператор amp;amp; в логике означает «и», который возвращает значение true только в том случае, если оба условия истинны. Итак, сначала проверяется левое условие, и если оно ложно, то правое условие не проверяется. Из-за этого я предлагаю вам поставить условия в таком порядке (чем выше в этом порядке должно быть левое условие).:
- Необходимо проверить перед условиями работы (например, не нулевые условия).
- Условия низкой временной сложности (например, проверка значения переменной).
- Условия высокой временной сложности (например, поиск в/сортировка массива).
Ответ №4:
Для того, чтобы оператор amp;amp; извлекал значение true, все условия должны возвращать значение true, поэтому мы сначала проверяем левые условия, и только если оно верно, мы проверяем все остальные одно за другим, если какое-либо условие не выполняется, мы прекращаем проверку всех остальных.
Поэтому в вашем случае вам сначала нужно выполнить все операции низкой сложности
Подробнее читайте об оценке короткого замыкания
Комментарии:
1. Сначала проверяется состояние слева. Такое поведение называется оценкой короткого замыкания.