Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Ленивая инициализация при валидном значении NULL / 25 сообщений из 43, страница 1 из 2
18.02.2020, 09:54
    #39927786
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Подскажите, как вы делаете ленивую инициализацию поля класса, если NULL может быть валидным значением?

Классический пример:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  private String aValue = null;
  private String getAValue() {
    if (aValue == null)
      aValue = compute();
    return aValue;
  }

  private String compute() {
    // long and heavy computing
    System.out.println("Initiating");
    return null;
  }



При
Код: java
1.
2.
 String a1 = getAValue();
 String a2 = getAValue();



метод compute() будет выполнен 2 раза.
Как вы решаете эту проблему?
Нужно для Java 8.

1) Использовать доп флаг? Некрасиво.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
private String aValue = null;
  private boolean aValueRequireInit = true;
  private String getAValue() {
    if (aValueRequireInit) {
      aValue = compute();
      aValueRequireInit = false;
    }
    return aValue;
  }



2) Optional - isPresent не подходит => не работает
Код: java
1.
2.
3.
4.
5.
6.
7.
private Optional<String> aValue = Optional.empty();
  private String getAValue() {
    if (!aValue.isPresent()) { // при NULL isPresent() = false
      aValue = Optional.ofNullable(compute());
    }
    return aValue.orElse(null);
  }



3) Optional антипаттерн
Код: java
1.
2.
3.
4.
5.
6.
7.
  private Optional<String> aValue = null;
  private String getAValue() {
    if (aValue == null) {
      aValue = Optional.ofNullable(compute());
    }
    return aValue.orElse(null);
  }



Скажите что-нибудь!
...
Рейтинг: 0 / 0
18.02.2020, 10:13
    #39927792
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
java.util.EnumMap использует для подобного специальный объект:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    /**
     * Distinguished non-null value for representing null values.
     */
    private static final Object NULL = new Object() {
        public int hashCode() {
            return 0;
        }

        public String toString() {
            return "java.util.EnumMap.NULL";
        }
    };

    private Object maskNull(Object value) {
        return (value == null ? NULL : value);
    }

    @SuppressWarnings("unchecked")
    private V unmaskNull(Object value) {
        return (V)(value == NULL ? null : value);
    }



Все проверки с value - через maskNull()/unmaskNull().
...
Рейтинг: 0 / 0
18.02.2020, 10:27
    #39927803
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Alexander A. Sak,

Я так понимаю, что введение спец объекта схоже с использованием флага:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  private static final Optional<String> NULLABLE = Optional.of("NULL");
  private Optional<String> aValue = NULLABLE;
  private String getAValue() {
    if (NULLABLE.equals(aValue)) {
      aValue = Optional.ofNullable(compute());
    }
    return aValue.orElse(null);
  }



Такой смысл?
...
Рейтинг: 0 / 0
18.02.2020, 10:33
    #39927810
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Можно не смотреть так мелко и не экономить спички.
Ленивость делать не для поля, а для класса.
Тогда флаг инициализации уместен. Ну или айди всегда не null.
...
Рейтинг: 0 / 0
18.02.2020, 10:43
    #39927819
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp,

PetroNotC Sharp
Ленивость делать не для поля, а для класса.

В моем случае - пишу некий "ютилити класс", который создает кучу тяжелых объектов разных типов (через обращение к БД, вызов сервисов, т.д. - короче затратная по времени инициализация).
Изменять удаленные методы не могу (чтобы возвращались не NULL).
Объекты используются не все и не всегда (в зависимости от условий)-> иницализация нужна ленивая.
В таком контексте делать весь класс ленивым, наверное, нет смысла...
...
Рейтинг: 0 / 0
18.02.2020, 10:44
    #39927821
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
Alexander A. Sak,

Я так понимаю, что введение спец объекта схоже с использованием флага:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  private static final Optional<String> NULLABLE = Optional.of("NULL");
  private Optional<String> aValue = NULLABLE;
  private String getAValue() {
    if (NULLABLE.equals(aValue)) {
      aValue = Optional.ofNullable(compute());
    }
    return aValue.orElse(null);
  }



Такой смысл?


Типа того. Только в этом примере наверное getValue() будет возвращать null, если compute() вернет "NULL".
Или проверку делать if (aValue == NULLABLE) или вообще делать без Optional, а в NULLABLE поместить какую-то строку, которой заведомо не будет получаться в compute().
...
Рейтинг: 0 / 0
18.02.2020, 10:46
    #39927822
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Тогда это специализированный класс и делай флаги хоть на каждое поле. Можно даже кеш запомнить или дату обновления.
Не усложняй.
...
Рейтинг: 0 / 0
18.02.2020, 10:50
    #39927826
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp,

PetroNotC Sharp
Тогда это специализированный класс и делай флаги хоть на каждое поле. Можно даже кеш запомнить или дату обновления.


Сейчас так и сделал на флагах. Но каждый раз, как смотрю на класс с мусорными флагами, начинает коробить
...
Рейтинг: 0 / 0
18.02.2020, 10:58
    #39927833
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
PetroNotC Sharp,

PetroNotC Sharp
Ленивость делать не для поля, а для класса.

В моем случае - пишу некий "ютилити класс", который создает кучу тяжелых объектов разных типов (через обращение к БД, вызов сервисов, т.д. - короче затратная по времени инициализация).
Изменять удаленные методы не могу (чтобы возвращались не NULL).
Объекты используются не все и не всегда (в зависимости от условий)-> иницализация нужна ленивая.
В таком контексте делать весь класс ленивым, наверное, нет смысла...
вот где у тебя обоснование невозможности сделать ленивые классы?
1 ты написал что пишешь утилитный класс. Ну и что?
2. Ты написал что сервисы возвращают null. Так бывает.
3. "объекты используются не всегда".... Ну а кто против? Мы же о ленивой говорим.
То есть где ответ на мой вопрос?
...
Рейтинг: 0 / 0
18.02.2020, 11:09
    #39927845
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp
То есть где ответ на мой вопрос?

Ну тогда я не понял, что ты имеешь под
PetroNotC Sharp
Vladmir K,
Ленивость делать не для поля, а для класса.

?
Обернуть каждое поле в класс?
...
Рейтинг: 0 / 0
18.02.2020, 11:11
    #39927848
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Чтобы ответить надо знать задачу выше уровнем.
Ты пишешь свой ОРМ вместо хибера?
То есть ты без маппинга рожаешь/формируешь класс из бд по полям.
Так?
...
Рейтинг: 0 / 0
18.02.2020, 11:13
    #39927849
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Напиши код использования твоегo класса MyUtils()
...
Рейтинг: 0 / 0
18.02.2020, 11:39
    #39927866
mad_nazgul
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Код: java
1.
data class Foo(var aValue: String? = null)


<:o)
...
Рейтинг: 0 / 0
18.02.2020, 11:41
    #39927868
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp
Напиши код использования твоегo класса MyUtils()


Хех... ну если сильно упрощенно.
Допустим, формируем некий Payload POJO класс для последующей сериализации в JSON
(проверки на NULL и иже с ним опущены для упрощения)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
  public void build() {
    ...
    aPOJO.setInvoiceNumber(getInvoice().getNumber());
    aPOJO.setInvoiceDate(getInvoice().getDate());
    ..
    aPOJO.setPaymentTerms(getPaymentTermsService(getInvoice()));
    ..
    aPOJO.setInstruction(getInvoiceHeaderInstructions());
   ..
    aPOJO.setTrufficInfo(getTraffic())

  }
  
  // Lazy
  private Invoice getInvoice() {
    // get's invoice from Web Service
  }

  // Lazy
  private BillOfLading getBOL() {
    // get's Bill of lading
  }

// getBOL(), getInvoice() вызываются многократно для получения другой информации.

 private TrufficInfo() {
   return  getBOL().getTruffic();
 }

  private Instruction getInvoiceHeaderInstructions() {
    return getInvoice().getInstructon();
  }
...
Рейтинг: 0 / 0
18.02.2020, 12:23
    #39927902
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
Так. ОРМ не используем.
А это?
5 января 2019 г. - финальная версия JSON-B API 1.0.1
http://json-b.net/
авторJSON-B - это стандартный уровень привязки для преобразования объектов Java в сообщения JSON. Он определяет алгоритм отображения по умолчанию для преобразования существующих классов Java в JSON, а также позволяет разработчикам настраивать процесс отображения с помощью аннотаций Java.
...
Рейтинг: 0 / 0
18.02.2020, 12:45
    #39927908
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
PetroNotC Sharp
Напиши код использования твоегo класса MyUtils()


Хех... ну если сильно упрощенно.
Допустим, формируем некий Payload POJO класс для последующей сериализации в JSON
(проверки на NULL и иже с ним опущены для упрощения)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
  public void build() {
    ...
    aPOJO.setInvoiceNumber(getInvoice().getNumber());
    aPOJO.setInvoiceDate(getInvoice().getDate());
    ..
    aPOJO.setPaymentTerms(getPaymentTermsService(getInvoice()));
    ..
    aPOJO.setInstruction(getInvoiceHeaderInstructions());
   ..
    aPOJO.setTrufficInfo(getTraffic())

  }
  
  // Lazy
  private Invoice getInvoice() {
    // get's invoice from Web Service
  }

  // Lazy
  private BillOfLading getBOL() {
    // get's Bill of lading
  }

// getBOL(), getInvoice() вызываются многократно для получения другой информации.

 private TrufficInfo() {
   return  getBOL().getTruffic();
 }

  private Instruction getInvoiceHeaderInstructions() {
    return getInvoice().getInstructon();
  }


Значит, по логике, у тебя уже 2 ленивых класса а не метода
Invoice, BillOfLading
В них сделать по флагу о том что из бд взяли все поля.
?
...
Рейтинг: 0 / 0
18.02.2020, 12:47
    #39927910
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Тогда сам этот код выше останется без изменений.
...
Рейтинг: 0 / 0
18.02.2020, 12:51
    #39927912
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Ну и можно добавить версию как в хибере.
При любом запросе, объект лезет в бд и сравнивает версию со своей. Если устарел, то переобновится весь.
Хотя это более затратно.
...
Рейтинг: 0 / 0
18.02.2020, 13:02
    #39927917
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp,

PetroNotC Sharp
Так. ОРМ не используем.

А на что это влияет? Внутри сервисов (например с помощью которого Invoice возвращается) используется, конечно.

PetroNotC Sharp
JSON-B API

Jackson было решено использовать.
...
Рейтинг: 0 / 0
18.02.2020, 13:06
    #39927922
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
А на что это влияет? Внутри сервисов (например с помощью которого Invoice возвращается) используется, конечно.
ну дак, сущность сразу обозначить в хибере ту которая в json пойдет нельзя было?
...
Рейтинг: 0 / 0
18.02.2020, 13:08
    #39927928
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K,
При rest часто сущности как они есть выставляем наружу в http/json.
Возможно у вас комбинированная Бизнес сущность из трех entity сущностей в бд.
...
Рейтинг: 0 / 0
18.02.2020, 13:14
    #39927930
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp
Значит, по логике, у тебя уже 2 ленивых класса а не метода
Invoice, BillOfLading


Объекты этих типов возвращаются сервисами. Их менять нельзя.
Т.е., если следовать твоей рекомендации, то мне нужно писать для них обертки. Ход мысли понятен. Спасибо.

PetroNotC Sharp
Ну и можно добавить версию как в хибере.
При любом запросе, объект лезет в бд и сравнивает версию со своей. Если устарел, то переобновится весь.
Хотя это более затратно.

Можно, это понятно. Но в моем случае, просто избыточно: Время жизни Util класса ограничено, фактически, вызовом основного метода build(). Проблема, что внутри метода build() постоянно дергаются тяжелые объекты, которые я хочу инициировать 1 раз.
...
Рейтинг: 0 / 0
18.02.2020, 13:16
    #39927933
Vladmir K
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
PetroNotC Sharp
Vladmir K
А на что это влияет? Внутри сервисов (например с помощью которого Invoice возвращается) используется, конечно.
ну дак, сущность сразу обозначить в хибере ту которая в json пойдет нельзя было?


Если бы можно, то и вопроса бы не было :) Система "сторонняя".
...
Рейтинг: 0 / 0
18.02.2020, 13:22
    #39927941
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
Объекты этих типов возвращаются сервисами. Их менять нельзя.
Т.е., если следовать твоей рекомендации, то мне нужно писать для них обертки. Ход мысли понятен. Спасибо.
да. Удачи!
...
Рейтинг: 0 / 0
18.02.2020, 16:16
    #39928067
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ленивая инициализация при валидном значении NULL
Vladmir K
PetroNotC Sharp,

PetroNotC Sharp
Ленивость делать не для поля, а для класса.

В моем случае - пишу некий "ютилити класс", который создает кучу тяжелых объектов разных типов (через обращение к БД, вызов сервисов, т.д. - короче затратная по времени инициализация).
Изменять удаленные методы не могу (чтобы возвращались не NULL).
Объекты используются не все и не всегда (в зависимости от условий)-> иницализация нужна ленивая.
В таком контексте делать весь класс ленивым, наверное, нет смысла...

По смыслу все твои объекты - ленивые синглтоны.

Посмотри еще в сторону Scala. Там есть lazy val. Кажется это то что ты ищешь.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Ленивая инициализация при валидном значении NULL / 25 сообщений из 43, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]