Откройте для себя лучший способ подсчета вещей в Java.
Использование карты для подсчета бусин на счетах
Вот простая задача, которую можно решить с помощью Map
. Как мы можем посчитать количество бусинок на счетах по цвету? Сначала я определю enum
для Color
.
Далее я создам HashMap<Color, Integer>
и использую метод merge
для сложения и вычитания значений для определенных цветов. Я не буду учитывать одну цветную бисеринку (Color.RED
). Затем я утверждаю результат запроса Map
для подсчета цветов с помощью Map.get
.
Я использую одну и ту же операцию merge
для сложения и вычитания. Я использую отрицательные значения Integer
для вычитания. Я использую ссылку на метод Integer::sum
для параметра BiFunction
, который принимает метод merge
, чтобы определить, как объединять значения. Обратите внимание, что хотя я использую здесь примитивные литеральные значения int
, они автоматически упаковываются как объекты Integer
в Map
., а вызов Integer::sum
приведет к большему распаковыванию и упаковке Integer
объектов.
В последнем утверждении теста вызов get
с экземпляром Color.RED
возвращает null
. Мне пришлось бы явно установить значение 0
, чтобы оно возвращалось как 0
при вызове get
. Один из способов решить проблему возврата null
с get
— использовать вместо него getOrDefault
. Это позволит вам вернуть значение по умолчанию в случае, если ключ не существует в файле Map
.
Оба метода merge
и getOrDefault
были добавлены в Java 8 и являются полезными для понимания разработчиками в Map
.
Использование примитивной карты вместо карты
В Eclipse Collections есть поддержка примитивных карт. Существует тип ObjectIntMap
и соответствующая реализация, которую можно использовать для подсчета бусин. Я буду использовать MutableObjectIntMap
, чтобы я мог видоизменять карту и создавать реализацию с помощью фабричного класса ObjectIntMaps
.
У MutableObjectIntMap
есть метод addToValue
, который можно использовать для добавления нового значения на карту или добавления к существующему значению на карте. Метод getIfAbsent
можно использовать для поиска значений. Значение 0
является объектом int
, а не Integer
, и ни один из вызовов addToValue
не приводит ни к какой упаковке.
Примечание. Класс Eclipse Collections HashBag
использует класс MutableObjectIntMap
.
Использование мешка для подсчета бусинок на счетах
Итак, как бы я решил эту проблему, используя MutableBag
из Eclipse Collections? MutableBag
- это Collection
, а не Map
. У него есть методы add
и remove
, которые я могу использовать для добавления отдельных элементов. MutableBag
также имеет методы addOccurrences
и removeOccurrences
, которые позволяют добавлять определенное количество элементов одновременно.
Методы с индивидуальными именами в Bag
лучше раскрывают намерения, чем единственный метод с именем merge
для этого варианта использования. Обратите внимание, что в случае Color.RED
Bag вернет 0
из вызова occurrencesOf
. Bag
не страдает от проблемы null
, которая есть у Map.get
. Если значение не существует в Bag
, метод occurrencesOf
всегда возвращает 0
.
Больше информации
Есть еще несколько блогов, которые предоставляют более подробную информацию о типе Bag
и поддерживающих методах, таких как countBy
в Eclipse Collections. Следующий блог был написан Нихилом Нанивадекаром. В нем описываются многие детали реализации типа Bag
в коллекциях Eclipse, которые могут привести к выигрышу как в памяти, так и в производительности.
Я также написал отдельный блог, описывающий метод countBy
в коллекциях Eclipse, который возвращает Bag
в качестве возвращаемого типа.
Надеюсь, вам понравилось читать этот блог и вы узнали что-то полезное о типах Map
и Bag
!
Я являюсь руководителем и ответственным за проект OSS Eclipse Collections в Eclipse Foundation. Eclipse Collections открыт для пожертвований. Если вам нравится библиотека, сообщите нам об этом, пометив ее звездочкой на GitHub.
Другие Статьи по Java, которые могут вам понравиться