powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Ленивая инициализация при валидном значении NULL
25 сообщений из 43, страница 1 из 2
Ленивая инициализация при валидном значении NULL
    #39927786
Vladmir K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, как вы делаете ленивую инициализацию поля класса, если 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
Ленивая инициализация при валидном значении NULL
    #39927792
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Ленивая инициализация при валидном значении NULL
    #39927803
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);
  }



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

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

В моем случае - пишу некий "ютилити класс", который создает кучу тяжелых объектов разных типов (через обращение к БД, вызов сервисов, т.д. - короче затратная по времени инициализация).
Изменять удаленные методы не могу (чтобы возвращались не NULL).
Объекты используются не все и не всегда (в зависимости от условий)-> иницализация нужна ленивая.
В таком контексте делать весь класс ленивым, наверное, нет смысла...
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927821
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Ленивая инициализация при валидном значении NULL
    #39927822
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladmir K,
Тогда это специализированный класс и делай флаги хоть на каждое поле. Можно даже кеш запомнить или дату обновления.
Не усложняй.
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927826
Vladmir K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp,

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


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

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

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

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

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


<:o)
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927868
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();
  }
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927902
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladmir K,
Так. ОРМ не используем.
А это?
5 января 2019 г. - финальная версия JSON-B API 1.0.1
http://json-b.net/
авторJSON-B - это стандартный уровень привязки для преобразования объектов Java в сообщения JSON. Он определяет алгоритм отображения по умолчанию для преобразования существующих классов Java в JSON, а также позволяет разработчикам настраивать процесс отображения с помощью аннотаций Java.
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927908
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Ленивая инициализация при валидном значении NULL
    #39927910
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда сам этот код выше останется без изменений.
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927912
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и можно добавить версию как в хибере.
При любом запросе, объект лезет в бд и сравнивает версию со своей. Если устарел, то переобновится весь.
Хотя это более затратно.
...
Рейтинг: 0 / 0
Ленивая инициализация при валидном значении NULL
    #39927917
Vladmir K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp,

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

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

PetroNotC Sharp
JSON-B API

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


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

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

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


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

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

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

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

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


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