Инверсия управления в лямбде

Я пытаюсь преобразовать список в ключи Map и имею значения по умолчанию null.
Однако мой код требует создания HashMap с помощью ключевого слова new, что противоречит принципу инверсии управления в Spring.

Могу ли я узнать, есть ли в Spring какой-нибудь правильный способ инициализировать карту в этой ситуации?

convertStringToList(input).stream().collect(HashMap::new, 
             (map, value) -> map.put(value, null), Map::putAll);

Вы слишком строго относитесь к МОК. Нет ничего плохого в том, чтобы создать HashMap с новым.

Henry 21.12.2018 08:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
1
179
2

Ответы 2

Вы не должны использовать ручное создание экземпляров компонентов, специфичных для Spring, таких как репозитории, службы, классы конфигурации и т. д. Однако совершенно нормально вручную создавать экземпляры карт и классов коллекций для реализации логики вашей предметной области.

Автоматическое подключение bean-компонентов Spring немного отличается от экземпляра конкретной реализации компонентов, не настроенных Spring. Не бойтесь ключевого слова new и определенной реализации.

Map<String, String> newMap = convertStringToList(input).stream().collect(HashMap::new, 
         (map, value) -> map.put(value, null), Map::putAll);

Это нормально, поскольку вы собираете Stream в Map, который является интерфейсом. Spring не влияет на то, какая реализация будет использоваться при сборе потока, поэтому вы должны указать, что будет использоваться HashMap (а не TreeMap, например ...).

Если да ...

 Map<String, String> a = b.stream().collect(Map::new, 
         (map, value) -> map.put(value, null), Map::putAll);

Вот вам "Cannot instantiate the type Map" - он нуждается в реализации, и Spring не обязан ее предоставлять.

Спасибо всем и Николаю за подробное объяснение! Просто любопытно (и для моего собственного обучения), почему нельзя использовать Collections.EMPTY_MAP вместо HashMap :: new? Это из-за неизменности Collections.EMPTY_MAP?

newdeveloper1111 24.12.2018 03:02

Прошу прощения за поздний ответ. Вам нужен Supplier<Map<K, V>> (() -> new HashMap<>() равен HashMap::new), поэтому () -> Collections.EMPTY_MAP или лучше () -> Collections.emptyMap(). Однако это неизменяемые версии Map, и метод Map::putAll выбрасывает UnsupportedOperationException. Более того, если вы посмотрите на исходный код Collections.emptyMap(), вы увидите, что он возвращает экземпляр частного статического класса Map.EmptyMap, который является пустой навигационной и неизменяемой картой.

Nikolas Charalambidis 26.12.2018 17:48

Другие вопросы по теме