Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Тернарная проверка на NULL  [new]
mesier
Member

Откуда: Новокузнецк ► СПб
Сообщений: 1043
Сори, если вопрос глупый, но что-то не могу допереть..
ac.getPs() ? "P" : "S"

- Здесь getPS() возвращает Boolean, и, как оказалось, может быть NULL, соответственно с бросанием NPE..
А можно как-то одной строкой, не мостряча доп.проверку, например, также тернарным оператором, проверить на NULL, и, если не NULL, то вернуть соответствующие значения?
12 мар 19, 17:18    [21830543]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7443
Java это боль
Смирись
12 мар 19, 17:23    [21830552]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Kachalov
Member

Откуда: Москва
Сообщений: 5565
mesier
А можно как-то одной строкой, не мостряча доп.проверку, например, также тернарным оператором, проверить на NULL, и, если не NULL, то вернуть соответствующие значения?

- если null считать за false, то:
Boolean.TRUE.equals(ac.getPs()) ? "P" : "S"

- если null значащий:
ac.getPs() == null ? "some" : ac.getPs() ? "P" : "S"
12 мар 19, 17:34    [21830573]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
mesier
Сори, если вопрос глупый, но что-то не могу допереть..
ac.getPs() ? "P" : "S"

- Здесь getPS() возвращает Boolean, и, как оказалось, может быть NULL, соответственно с бросанием NPE..
А можно как-то одной строкой, не мостряча доп.проверку, например, также тернарным оператором, проверить на NULL, и, если не NULL, то вернуть соответствующие значения?

Поскольку тернарная операция - это функция - то ты должен определить семантику NULL значения.
Ты не можешь вернуть НИЧЕГО.

С другой стороны если посмотреть на код который обрамляет эту функцию - то попробуй
перейти на Groovy с использованием null-safe operator. Это синтаксический сахар который
позволяет игнорировать действия над null-полями в объекте. И игнорировать рекурсивно
во вложениях.

Попробуй отказаться от Boolean и перейти на boolean-примитив если можно.
12 мар 19, 20:01    [21830688]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
Optional.ofNullable(ac.getPs()).map(b -> b ? "P" : "S").orElse("null")
13 мар 19, 10:28    [21831027]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
betelgeizex
Optional.ofNullable(ac.getPs()).map(b -> b ? "P" : "S").orElse("null")
полностью извратился смысл компактного и читабельного. имхо
13 мар 19, 10:59    [21831058]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Petro123
betelgeizex
Optional.ofNullable(ac.getPs()).map(b -> b ? "P" : "S").orElse("null")
полностью извратился смысл компактного и читабельного. имхо

Тернарная операция все равно приятнее.
13 мар 19, 11:31    [21831093]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
mayton
Petro123
пропущено...
полностью извратился смысл компактного и читабельного. имхо

Тернарная операция все равно приятнее.


"читабельнее" и "приятнее" - это чисто субъективный понятия :)
Мне, например, линейная цепочка вычислений более наглядна, чем пачка вложенных 'if'-ов v. пусть и с компактным синтаксисом.

if (ac.getPs() == null) then "some" else ( if (ac.getPs()) then "P" else "S")


А вот то, что в варианте тернарного оператора дважды вызывается getPs() - это объективный недочет.
13 мар 19, 12:14    [21831144]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mesier
Member

Откуда: Новокузнецк ► СПб
Сообщений: 1043
betelgeizex
Мне, например, линейная цепочка вычислений более наглядна, чем пачка вложенных 'if'-ов v. пусть и с компактным синтаксисом.
if (ac.getPs() == null) then "some" else ( if (ac.getPs()) then "P" else "S")


Вам такая запись может и нагляднее, но объективно это не в нотации, и вообще, у меня редактор сам переносы расставит.. ))
betelgeizex
А вот то, что в варианте тернарного оператора дважды вызывается getPs() - это объективный недочет.

А что делать!... В if-ах третьего-то не дано, приходится вот так.
13 мар 19, 12:36    [21831180]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
mesier
betelgeizex
...
if (ac.getPs() == null) then "some" else ( if (ac.getPs()) then "P" else "S")

Вам такая запись может и нагляднее, но объективно это не в нотации, и вообще, у меня редактор сам переносы расставит.. ))



Разумеется, это не Java; это то, вот что у меня в голове превращается вариант с тернарным оператором :)

И это как раз я считаю _менее_ наглядным, чем вариант с Optional.

mesier

betelgeizex
А вот то, что в варианте тернарного оператора дважды вызывается getPs() - это объективный недочет.

А что делать!... В if-ах третьего-то не дано, приходится вот так.


Даже если сейчас getPs() - тупой геттер, то через какое-то время в него могут попасть весьма тяжелые вычисления.
Надо избегать нескольких вызовов!
Например, сохранить результат в переменную, но тогда "как-то одной строкой" не получится.

А чем вас не устраивает однострочник с Optional ? Ну, кроме того, что символов больше? )
13 мар 19, 12:49    [21831202]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
betelgeizex
mayton
пропущено...

Тернарная операция все равно приятнее.


"читабельнее" и "приятнее" - это чисто субъективный понятия :)
Мне, например, линейная цепочка вычислений более наглядна, чем пачка вложенных 'if'-ов v. пусть и с компактным синтаксисом.

if (ac.getPs() == null) then "some" else ( if (ac.getPs()) then "P" else "S")


А вот то, что в варианте тернарного оператора дважды вызывается getPs() - это объективный недочет.

Надо всегда смотреть в стек. Сначала language. Его возможности. По максимуму решить задачу на этом уровне.
Тернарная операция это уровень языка. Самое перформансное решениею. Тем более что агрессивный оптимизатор
уже на этом уровне может строить свои предположения об оптимизации и вводить временные переменные и тому
подобное. Сюда-же до кучи null-безопасное разыменование (если оно поддерживается в языке) как в Groovy.

Второй уровень - библиотеки. Optional.

Но проблема топика как всегда в изначальной постановке. Кому вообще нужен Boolean стройной логикой?
Что это за смысл? Да. Нет. И неопределено.
13 мар 19, 12:57    [21831213]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
betelgeizex
"читабельнее" и "приятнее" - это чисто субъективный понятия :)
вариант Kachalov лучше вашего. Вот и все.
13 мар 19, 12:58    [21831216]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
С тройной логикой я имел в виду. true|false|null
13 мар 19, 13:00    [21831220]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
mayton
Тернарная операция это уровень языка
+1
И мне по барабану что двойной вызов.
Прикладник вызубрит эту особенность в оперативной памяти. Пока косяк не устранят.
13 мар 19, 13:00    [21831222]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
mayton
...
Надо всегда смотреть в стек. Сначала language. Его возможности. По максимуму решить задачу на этом уровне.
Тернарная операция это уровень языка. Самое перформансное решениею. Тем более что агрессивный оптимизатор
уже на этом уровне может строить свои предположения об оптимизации и вводить временные переменные и тому
подобное. Сюда-же до кучи null-безопасное разыменование (если оно поддерживается в языке) как в Groovy.

Второй уровень - библиотеки. Optional.



Так можно далеко зайти...
Пример: 'new' - уровень языка, DI container - библиотека.
Давайте откажемтся от DI и будем передавать зависимости руками? По максимуму использовать язык... ))


mayton
Но проблема топика как всегда в изначальной постановке. Кому вообще нужен Boolean стройной логикой?
Что это за смысл? Да. Нет. И неопределено.


Например, флаг, пришедший из БД. Или Query-параметр. Да куча вариантов.
13 мар 19, 13:06    [21831225]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Alexey Tomin
Member

Откуда: Самара
Сообщений: 1648
А просто функцию сделать?

<T> T nvl2(Boolean b, T whenTrue, T whenFalse, T whenNull) {
...
}
13 мар 19, 13:10    [21831233]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
Petro123
betelgeizex
"читабельнее" и "приятнее" - это чисто субъективный понятия :)
вариант Kachalov лучше вашего. Вот и все.


Давайте на этом и остановимся. Конечно, вы правы.
13 мар 19, 13:13    [21831235]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
Alexey Tomin
А просто функцию сделать?

<T> T nvl2(Boolean b, T whenTrue, T whenFalse, T whenNull) {
...
}


Это самый лучший вариант. Серьезно, этакий DSL... Но ТС хотел одной строкой, не мостряча )
13 мар 19, 13:18    [21831251]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Владимир П.
Member

Откуда: Екатеринбург
Сообщений: 434
Alexey Tomin
А просто функцию сделать?
<T> T nvl2(Boolean b, T whenTrue, T whenFalse, T whenNull) {
...
}

Тогда при вызове этой функции придётся пожертвовать принципом «short-circuit boolean evaluation», что не всегда приемлемо. Возможно, более удачным будет вариант с применением лямбд:

<T> T nvl2(Boolean b, Supplier<T> whenTrueSupplier, Supplier<T> whenFalseSupplier, Supplier<T> whenNullSupplier) {
...
}
13 мар 19, 13:21    [21831258]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 4849
Владимир П.
Alexey Tomin
А просто функцию сделать?
<T> T nvl2(Boolean b, T whenTrue, T whenFalse, T whenNull) {
...
}

Тогда при вызове этой функции придётся пожертвовать принципом «short-circuit boolean evaluation», что не всегда приемлемо. Возможно, более удачным будет вариант с применением лямбд:

<T> T nvl2(Boolean b, Supplier<T> whenTrueSupplier, Supplier<T> whenFalseSupplier, Supplier<T> whenNullSupplier) {
...
}


не, можно еще усложнить...наверное
13 мар 19, 13:29    [21831269]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Владимир П.
Member

Откуда: Екатеринбург
Сообщений: 434
Озверин
не, можно еще усложнить...наверное

Нафига?
13 мар 19, 13:30    [21831274]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
betelgeizex
Например, флаг, пришедший из БД. Или Query-параметр. Да куча вариантов.

Хорошо. Расскажите мне семантику этого флага. У нег 3 состояния.

Может стоило ввести 3 константы?
13 мар 19, 13:48    [21831302]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
betelgeizex
Так можно далеко зайти...
Пример: 'new' - уровень языка, DI container - библиотека.
Давайте откажемтся от DI и будем передавать зависимости руками? По максимуму использовать язык... ))

Я протестую! Я этого не говорил. Аналогии с new/DI вообще неуместны.
Не стоит додумывать и добавлять новые смыслы. Моя позиция была
только по синтаксису логических условий.
13 мар 19, 13:51    [21831308]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
mayton
betelgeizex
Например, флаг, пришедший из БД. Или Query-параметр. Да куча вариантов.

Хорошо. Расскажите мне семантику этого флага. У нег 3 состояния.

Может стоило ввести 3 константы?


Состояния очевидные: "Ответил ДА" / "Ответил НЕТ" / "Не ответил"

Можно ввести 3 статуса, не вопрос.
Но я бы не плодил новых сущностей и использовал бы всем известную семантику NULL-полей в RDBMS.

Как контрпример, можно рассмотреть другую семантику: "ДА"/"НЕТ"/"НЕ ПРИМЕНИМО" - вот тут три константы будут удобнее.
13 мар 19, 14:08    [21831334]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
am_sasa
Member

Откуда:
Сообщений: 701
betelgeizex,

А для юзер интерфейса надо так:

да / нет / не знаю
13 мар 19, 14:16    [21831341]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
betelgeizex
Member

Откуда:
Сообщений: 32
mayton
betelgeizex
Так можно далеко зайти...
Пример: 'new' - уровень языка, DI container - библиотека.
Давайте откажемтся от DI и будем передавать зависимости руками? По максимуму использовать язык... ))

Я протестую! Я этого не говорил. Аналогии с new/DI вообще неуместны.
Не стоит додумывать и добавлять новые смыслы. Моя позиция была
только по синтаксису логических условий.


Ну, вы указали на общность фразы:

автор
Надо всегда смотреть в стек. Сначала language. Его возможности. По максимуму решить задачу на этом уровне...

Вот я и решил развить мысль.


Я понимаю, что мог не уловить смысла. Но тогда вопрос: в чем синтаксис логических условий принципиально отличается от остальных аспектов языка?
Почему для логических условий надо использовать язык по максимуму (предпочитая его библиотекам), я для прочих задач такой посыл вами не утверждается?
13 мар 19, 14:20    [21831347]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Давайте вернёмся к теме.
13 мар 19, 14:28    [21831361]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
teo609
Member

Откуда: Рязань
Сообщений: 103
mesier
Сори, если вопрос глупый, но что-то не могу допереть..
ac.getPs() ? "P" : "S"

- Здесь getPS() возвращает Boolean, и, как оказалось, может быть NULL, соответственно с бросанием NPE..
А можно как-то одной строкой, не мостряча доп.проверку, например, также тернарным оператором, проверить на NULL, и, если не NULL, то вернуть соответствующие значения?


мне кажется, что null здесь может быть не getPS(), а ас.
Тогда все упрощается (далее по примеру от Kachalov)

ac == null ? "ac is null" : ac.getPs() ? "P" : "S"

потому что даже если getPS возвращает null, то для NPE нет повода, поскольку по этому null доступ не производится.
13 мар 19, 17:33    [21831592]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Скорее всего у него используется Orm-фреймворк который формирует entity корректно
(не null) а различные поля этой entity вполне могут быть null ибо такова есть база данных.
Помним что реляционная алгебра позволяет делать дырки в таблице и это норм. Это не
дефект. И я думаю что его беспокоит именно предикат ac.getPs() == null т.к. она ломает
обычный порядок исполнения тернаной операции и заставляет делать еще одну лишнюю
проверку.
13 мар 19, 17:40    [21831605]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
teo609
Member

Откуда: Рязань
Сообщений: 103
mayton,

я банально перепутал Boolean с boolean, почти не писал на яве.

А к вашему вопросу о логике трех состояний, ссылочный Boolean обусловлен языком, поэтому зачем ставить вопрос о его прикладной логике.
Кстати, поэтому и Optional мне не нравится как средство проверки на null, ведь логика может быть другой. Опциональность значения это по хорошему вопрос дизайна, а наличие null в ссылке может говорить не об этом, а об аварийной ситуации в процессе получения значения.
13 мар 19, 17:51    [21831618]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
teo609
mayton,

я банально перепутал Boolean с boolean, почти не писал на яве.

А к вашему вопросу о логике трех состояний, ссылочный Boolean обусловлен языком, поэтому зачем ставить вопрос о его прикладной логике.
Кстати, поэтому и Optional мне не нравится как средство проверки на null, ведь логика может быть другой. Опциональность значения это по хорошему вопрос дизайна, а наличие null в ссылке может говорить не об этом, а об аварийной ситуации в процессе получения значения.

В данном конкретном кейсе Optional не нужен я считаю. Хотя он очень полезен когда вы работаете со Streams.
13 мар 19, 18:03    [21831637]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mesier
Member

Откуда: Новокузнецк ► СПб
Сообщений: 1043
Alexey Tomin
А просто функцию сделать?
<T> T nvl2(Boolean b, T whenTrue, T whenFalse, T whenNull) {
...
}

Ну, да, вариант!
Хорошечно ещё и тем, что можно юнит-тест нарисовать. А то как-то юнит-тест для entity немного странно выглядит.. )))
13 мар 19, 18:12    [21831648]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mesier
Member

Откуда: Новокузнецк ► СПб
Сообщений: 1043
mayton
Скорее всего у него используется Orm-фреймворк который формирует entity корректно
(не null) а различные поля этой entity вполне могут быть null ибо такова есть база данных.
Помним что реляционная алгебра позволяет делать дырки в таблице и это норм. Это не
дефект. И я думаю что его беспокоит именно предикат ac.getPs() == null т.к. она ломает
обычный порядок исполнения тернаной операции и заставляет делать еще одну лишнюю
проверку.

Именно так.
13 мар 19, 18:13    [21831649]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
mesier
ac.getPs() ? "P" : "S"

Интересно, что в шарпе это не скомпилируется если null возможен в возврате getPs()
13 мар 19, 18:14    [21831651]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
mesier,
Если сущность, то не делай её тупой. Сделай поумнее, добавив метод возврата строки или
as.getPs().asString()
13 мар 19, 18:43    [21831683]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Petro123
mesier,
Если сущность, то не делай её тупой. Сделай поумнее, добавив метод возврата строки или
as.getPs().asString()

Это не совсем решение проблемы автора. Это просто перенос на другой уровень.
Кроме того надо помнить о потере соотвествия между ORM-entity и умной-entity.

Вобщем memento mori. Помни.
13 мар 19, 19:09    [21831711]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
mayton,
Да. Все надо учитывать.
Представь 200 свойств с null и все тут с тернарными и троичной логикой.
Это лапша код будет.
13 мар 19, 19:16    [21831713]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Я не могу себе представить одно бизнес-действие с 200 свойствами.

Как вариант serialzation или метод toString но для него нет проблемы NPE. Она решена
на коробочном уровне.
13 мар 19, 19:20    [21831720]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37071
mayton,
Я за то чтобы компилятор заругался на потенциальную ошибку.
Т.к. Для оператора? требуется только Да или Нет.
Imho
13 мар 19, 19:48    [21831766]     Ответить | Цитировать Сообщить модератору
 Re: Тернарная проверка на NULL  [new]
mayton
Member

Откуда: loopback
Сообщений: 39264
Согласен. Я-бы проверил исходник автора на SonarQube. Если тот заругается - то автор сам себе виноват. Не читает warnings.
13 мар 19, 19:53    [21831772]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Java Ответить