LINUX.ORG.RU

Новые Optional-ы

 


0

1

Как лучше?

старый добрый тернарный оператор

this.winnerAccountId = auction.getWinner() != null ? auction.getWinner().getId() : null;

новый Optional (со статическим импортом)

this.winnerAccountId = ofNullable(auction.getWinner()).map(winner -> winner.getId()).orElse(null);

свой маленький утилитный метод

this.winnerAccountId = nullableOp(auction.getWinner(), winner -> winner.getId(), null);

★★★★★
Ответ на: комментарий от vertexua

В первом случае повторение getWinner, можно опечататься. В третьем случае неочевидно, что происходит. Во втором случае как то многословно всё. Вот и хз, что лучше.

Legioner ★★★★★
() автор топика
Ответ на: комментарий от Legioner

многословно всё

Привыкай, сынок, это жаба. Она всегда была и будет многословной. Перепоределение операторов вам так и не завезли.

anonymous
()

По-моему, лучше будет первый вариант, но с auction.getWinner(), вынесенным в отдельную переменную.

CARS ★★★★
()

Какое всё-таки говно этот шашлычный стиль с map orElse

tailgunner ★★★★★
()

И да, не забываем, что Optional-ы придуманы для забугорных юных быдлокодеров, ибо те не могут понять что такое NullPointer. Вот.

ii8_ ★★★★
()
Последнее исправление: ii8_ (всего исправлений: 1)

Я бы завел отдельный метод (или даже два) и не использовал никаких Optional/анонимных классов:

this.winnerAccountId = getWinnerIdOrNull(auction);

private Long getWinnerIdOrNull(Auction auction) {
    if (auction == null) {
        return null;
    }

    return getWinnerIdOrNull(auction.getWinner());
}

private Long getWinnerIdOrNull(Winner winner) {
    if (winner == null) {
        return null;
    }

    return winner.getId();
}

php-coder ★★★★★
()
Последнее исправление: php-coder (всего исправлений: 1)

Первый вариант действительно плох тем, о чем ты написал. Но второй в этом плане тоже не лучше (а чем лучше писать .map(winner -> winner.getId()) вместо auction.getWinner() второй раз?), при этом длиннее. А третий плох тем, что без знания твоего кастомного nullableOp он не понятен. Поэтому я бы выбрал первый вариант, как меньшее из зол, но если таких конструкций много, то тогда — третий.

asaw ★★★★★
()
Ответ на: комментарий от ii8_

тогда уж не хоткей, а подсказка с желтой лампочкой

stevejobs ★★★★☆
()
Ответ на: комментарий от asaw

Но второй в этом плане тоже не лучше (а чем лучше писать .map(winner -> winner.getId()) вместо auction.getWinner() второй раз?)

Тем, что я не могу сделать опечатку вида auction.getWinner() != null ? auction.getLoser().getId() : null. winner -> winner.getId() это просто синтаксис, можно было бы просто написать map(Account::getId) или map(w -> w.getId()) (или map(_.getId()) если бы жава была скалой). Но суть не меняется, опечататься там нельзя.

Legioner ★★★★★
() автор топика

Как по мне, тернарные операторы тяжелее читать, чем простыню Optional, а 3-й вариант неудобен тем, что совсем не очевиден. Я выбираю Optional.

f1xmAn ★★★★★
()
Ответ на: комментарий от stevejobs

одну строчку кода раздул на полстраницы текста. зачем?

Читаемое название метода + предварительная генерализация.

«Вот так я развлекаюсь» (с)

php-coder ★★★★★
()
Ответ на: комментарий от Legioner

или map(_.getId() если бы жава была скалой

вся суть проблемы в семи словах :(

stevejobs ★★★★☆
()
Ответ на: комментарий от f1xmAn

Аналогично.

Я у себя еще и сделал аналоги скалы Some/Option/None и мои волосы гладкие и шелковистые.

anonymous
()
Ответ на: комментарий от stevejobs

Да это боян, кроме того, я стараюсь по возможности избегать намешивать библиотек, например, потому что и так до 8 йавы не было стандартного интерфейса для FunctionX, поэтому почти каждая либа свои намутила, и апдейтиться что-то никто не спешит, поэтому имеем свои function от гуавы, от javolution, в либах твиттера вроде были и т.д. С optional точно так же, ну и вообще. А иногда приходится между ними еще интероп налаживать, брр.

anonymous
()

А, и еще встречал предложение переходить на новые геттеры:

Optional<T> getT() {
    return Optional.ofNullable(t);
}

За счет этого ты не тратишь память на коробочки, но делаешь свои висячие nullы весьма безопасными.

anonymous
()

Накой черт у тебя во втором варианте .orElse(null)? Переведи все на оптион, код будет короче и второй вариант станет лучшим. А так ни туда ни сюда.

dizza ★★★★★
()
Ответ на: комментарий от f1xmAn

Да ладно, нормально отформатированный, одноуровневый читается легко.

nagibator
()
Ответ на: комментарий от dizza

Optional не предназначен, чтобы заменять nullable ссылки. Его единственная цель – явным образом указать, что метод может возвращать пустое значение. Применять его не по назначению (например для хранения опционального значения в поле) – потенциально сильно увеличить нагрузку на сборщик мусора. Для повсеместного применения Optional нужна поддержка со стороны VM (value-типы или замена Optional на простую ссылку со стороны VM).

Legioner ★★★★★
() автор топика
Ответ на: комментарий от ii8_

Optional'ы - это типы, в отличие от. Плохо что объекты все равно могут быть нулами.

anonymous
()
Ответ на: комментарий от Legioner

Вроде пишут, что переварит, если будет field-ы менять, а не property. Хороший совет, кстати, спасибо.

Legioner ★★★★★
() автор топика
Ответ на: комментарий от Legioner

Преждевременная оптимизация детектед. Теперь расскажите на каких гипотезах построен сборщик поколений в жабке, и как устроен сборщик молодого поколения.

dizza ★★★★★
()
Ответ на: комментарий от Legioner

Эх, Thymeleaf (а точнее Spring EL) не поддерживает Optional. Слишком некрасиво будет в шаблонах куча .get()-ов. Как начнут поддерживать, можно в моделях будет использовать.

Legioner ★★★★★
() автор топика
Ответ на: комментарий от dizza

Дело не в оптимизации, а в нежелании на ровном месте увеличивать число ссылок в 2 раза без какой-либо выгоды. К Optional-ам в геттерах-сеттерах, которые будут жить недолго, ничего не имею. Т.е. в объекте храним nullable refernce, в интерфейсе к нему Optional-ы.

Есть преждевременная оптимизация, а есть преждевременная пессимизация. Когда всё пишем заведомо медленно. Оно тоже накапливается, а исправлять это потом уже будет нереально. Вон в SQLite в каком то релизе сделали огромное число микрооптимизаций. Каждая давала доли процента в определённых use-case-ах. А в итоге скорость возросла на десятки процентов.

Legioner ★★★★★
() автор топика

Заведи интерфейс

Identifiable<T> { T getId(); }

и нарисуй к нему утилитный метод getOrNull и не пиши больше эту хрень

Deleted
()

или так с блямбдами

public class Nulls {
  public static <S, T> T getOrNull(S source, Function<S, T> function) {
    if(source == null) {
      return null;
    }
    return function.apply(source);
  }
}


//

Winner some = null;
assertEquals(null, Nulls.getOrNull(some, Winner::getId));
some = new Winner(1l);
assertEquals((Long)1l, Nulls.getOrNull(some, Winner::getId));

Deleted
()
Ответ на: комментарий от anonymous

По ссылке хреь какая-то. Бины сами по себе короткоживущие, либо синглтоны без состояния. Нагрузка на gc автору явно приснилась. И таки да, в java null и так означает отсутсвие значения, optional по смыслу тоже самое. Другое дело что есть nullable аннотация и checker framework. Поживем, увидим.

dizza ★★★★★
()
Последнее исправление: dizza (всего исправлений: 3)
Ответ на: комментарий от dizza

пора переходить на личности, ибо автор - весьма и весьма признанный авторитет, а ты со своей аватаркой создаешь впечатление фанбоя, поэму я все-таки останусь при своём мнении.

anonymous
()

но зачем? вместо одного уловия имеем +3 вызова функций, +3 временных объекта. джава уже не тормозит и не ест память гигабайтами, что пора усложнять?

exhu
()
Ответ на: комментарий от anonymous

1) так оно и нечитабельное нифига, какая ж тут оптимизация?!11 2) вот так и пишут софт, что определённого узкого места нет, просто тормоза размазаны по всей программе и профайл не помогает, проходили, знаем.

exhu
()
Последнее исправление: exhu (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.