<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Lobanov Typer</title><author><name>Lobanov Typer</name></author><id>https://teletype.in/atom/llax</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/llax?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@llax?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=llax"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/llax?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-05T07:19:56.405Z</updated><entry><id>llax:HMG0RNVYQd8</id><link rel="alternate" type="text/html" href="https://teletype.in/@llax/HMG0RNVYQd8?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=llax"></link><title>Абстрактная Фабрика</title><published>2025-07-23T08:30:03.600Z</published><updated>2025-07-23T08:30:03.600Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img3.teletype.in/files/a7/e5/a7e55603-061b-4952-8e8a-a5eae7612f9d.png"></media:thumbnail><category term="gof-patterns" label="Gof_Patterns"></category><tt:hashtag>java</tt:hashtag><tt:hashtag>gof</tt:hashtag><tt:hashtag>patterns</tt:hashtag><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/86/06/86068008-7291-4ab3-ac16-41f6b79ff433.png&quot;&gt;Абстрактная фабрика — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретные классы.</summary><content type="html">
  &lt;tt-tags id=&quot;zxDv&quot;&gt;
    &lt;tt-tag name=&quot;java&quot;&gt;#java&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;gof&quot;&gt;#gof&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;patterns&quot;&gt;#patterns&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;
  &lt;p id=&quot;QAPZ&quot;&gt;&lt;strong&gt;Абстрактная фабрика&lt;/strong&gt; — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретные классы.&lt;/p&gt;
  &lt;p id=&quot;cuet&quot;&gt;Паттерн решает проблему создания объектов, когда система должна быть независима от процесса их генерации, композиции и представления. Он используется, когда клиентскому коду необходимо работать с несколькими семействами продуктов, но при этом он не должен зависеть от конкретных классов этих продуктов.&lt;/p&gt;
  &lt;p id=&quot;5HAs&quot;&gt;Для этого &lt;u&gt;создаётся абстрактный класс-фабрика&lt;/u&gt; с набором абстрактных методов для создания каждого продукта в семействе. &lt;u&gt;Затем&lt;/u&gt; для каждой вариации семейства реализуется &lt;u&gt;конкретная фабрика&lt;/u&gt;, которая возвращает определённые, но гарантированно совместимые между собой, экземпляры продуктов. Клиентский код оперирует только интерфейсами (абстрактной фабрики и абстрактных продуктов), что позволяет легко заменять целые семейства объектов, просто подставляя другую реализацию фабрики.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;TmbK&quot;&gt;Другими словами&lt;/h3&gt;
  &lt;p id=&quot;rYPH&quot;&gt;Представьте, что вы пришли в IKEA. Вам нужен не просто стол, а полный комплект мебели для комнаты: стол, стул, шкаф и кровать. Главное — чтобы всё сочеталось по стилю.&lt;/p&gt;
  &lt;p id=&quot;PUo1&quot;&gt;Вы можете бегать по всему магазину и пытаться подобрать предметы по отдельности, рискуя ошибиться (например, взять стул в стиле хай-тек к столу в стиле прованс). А можете просто выбрать одну мебельную серию, например, «ХЕМНЭС». В этой серии все предметы уже созданы так, чтобы идеально подходить друг другу по цвету, материалу и дизайну.&lt;/p&gt;
  &lt;p id=&quot;wtXZ&quot;&gt;&lt;strong&gt;Абстрактная фабрика — это и есть этот «каталог серий» в мире программирования.&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;oQoh&quot;&gt;Вы выбираете одну «серию» (например, ФабрикаСтиляАр-деко), и она поставляет вам полный, гарантированно совместимый набор объектов (креслоАр-деко, диванАр-деко, столикАр-деко). Вам не нужно думать о деталях — только выбрать нужный стиль. А если захотите сменить его на «Модерн», вы просто возьмёте другой «каталог» (ФабрикуСтиляМодерн), не меняя свой основной код.&lt;/p&gt;
  &lt;h2 id=&quot;d0mP&quot;&gt;Проблема&lt;/h2&gt;
  &lt;p id=&quot;yTXV&quot;&gt;Представьте, что мы пишем симулятор выживания в мире после апокалипсиса. Важная часть игры — постройка убежищ. Код содержит:&lt;/p&gt;
  &lt;ol id=&quot;rIe1&quot;&gt;
    &lt;li id=&quot;y8AN&quot;&gt;&lt;strong&gt;Семейство зависимых компонентов.&lt;/strong&gt; Скажем, любое убежище состоит из Стены + Дверь + Источник питания.&lt;/li&gt;
    &lt;li id=&quot;QOcV&quot;&gt;&lt;strong&gt;Несколько вариаций этого семейства.&lt;/strong&gt; Например, компоненты Стены, Дверь и Источник питания могут быть собраны в разных стилях, в зависимости от доступных ресурсов и технологий: Хлам-тек (из подручных материалов), Военный (из армейских компонентов) и Высокотехнологичный (из довоенных научных разработок).&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;LDGn&quot;&gt;Вам нужно, чтобы компоненты убежища были совместимы друг с другом. Это важно, потому что выжившие не смогут установить бронированную дверь военного образца в хлипкую стену из металлолома. Несоответствие технологий может привести к катастрофе.&lt;/p&gt;
  &lt;p id=&quot;I1ju&quot;&gt;Кроме того, вы не хотите переписывать основной код игры каждый раз, когда добавляете новый тип убежищ или их компоненты. В мире игры могут найтись чертежи для постройки, например, Био-убежища, и вы бы не хотели менять существующую логику строительства при добавлении новых возможностей.&lt;/p&gt;
  &lt;h3 id=&quot;NMoZ&quot;&gt;Решение&lt;/h3&gt;
  &lt;p id=&quot;Z7Eh&quot;&gt;Для начала паттерн Абстрактная фабрика предлагает выделить общие интерфейсы для отдельных компонентов, составляющих убежище. Так, все вариации стен получат общий интерфейс Стена, все двери реализуют интерфейс Дверь и так далее.&lt;/p&gt;
  &lt;p id=&quot;Qbuj&quot;&gt;Далее вы создаёте абстрактную фабрику убежищ — общий интерфейс, который содержит методы создания всех компонентов семейства (например, создатьСтену, создатьДверь и создатьИсточникПитания). Эти операции должны возвращать &lt;strong&gt;абстрактные&lt;/strong&gt; типы компонентов, представленные интерфейсами, которые мы выделили ранее — Стена, Дверь и ИсточникПитания.&lt;/p&gt;
  &lt;p id=&quot;P3GY&quot;&gt;Как насчёт вариаций убежищ? Для каждой вариации (стиля) мы должны создать свою собственную фабрику, реализовав абстрактный интерфейс. Фабрики создают компоненты одной вариации. Например, ФабрикаВоенногоБункера будет возвращать только ЖелезобетонныеСтены, БронированнуюДверь и ДизельныйГенератор. Таким образом, клиентский код, отвечающий за постройку, получает фабрику и использует её для создания совместимых частей, не вникая в детали их реализации.&lt;/p&gt;
  &lt;h3 id=&quot;V15z&quot;&gt;Пример&lt;/h3&gt;
  &lt;p id=&quot;GlS4&quot;&gt;Для примера, предположим, что мы создаём убежища двух типов: из подручных материалов (Хлам-тек) и укрепленный военный бункер. Каждый тип убежища требует своих стен, двери и источника питания.&lt;/p&gt;
  &lt;pre id=&quot;HMSn&quot; data-lang=&quot;java&quot;&gt;// Интерфейс для стен убежища
interface Wall {
    void getDescription();
}

// Интерфейс для двери
interface Door {
    void getDescription();
}

// Интерфейс для источника питания
interface PowerSource {
    void getDescription();
}&lt;/pre&gt;
  &lt;p id=&quot;XIdB&quot;&gt;Теперь создадим конкретные реализации компонентов для убежища в стиле Хлам-тек:&lt;/p&gt;
  &lt;pre id=&quot;YOqz&quot; data-lang=&quot;java&quot;&gt;// Стена из металлолома
class ScrapWall implements Wall {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Стена, собранная из ржавого листового металла и мусора.&amp;quot;);
    }
}

// Дверь из досок и арматуры
class ScrapDoor implements Door {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Дверь, сколоченная из досок и укрепленная арматурой.&amp;quot;);
    }
}

// Генератор из старого автомобильного двигателя
class CarEngineGenerator implements PowerSource {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Источник питания: шумный генератор на базе автомобильного двигателя.&amp;quot;);
    }
}&lt;/pre&gt;
  &lt;p id=&quot;XuA5&quot;&gt;Теперь создадим аналогичные реализации для Военного бункера:&lt;/p&gt;
  &lt;pre id=&quot;Htmd&quot; data-lang=&quot;java&quot;&gt;// Железобетонная стена
class ReinforcedConcreteWall implements Wall {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Стена из армированного железобетона, выдержит небольшой взрыв.&amp;quot;);
    }
}

// Бронированная дверь-шлюз
class BlastDoor implements Door {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Герметичная бронированная дверь-шлюз.&amp;quot;);
    }
}

// Военный дизельный генератор
class MilitaryDieselGenerator implements PowerSource {
    @Override
    public void getDescription() {
        System.out.println(&amp;quot;Источник питания: надежный и мощный военный дизельный генератор.&amp;quot;);
    }
}&lt;/pre&gt;
  &lt;p id=&quot;JaYf&quot;&gt;Теперь определим интерфейс абстрактной фабрики, которая будет создавать наборы компонентов:&lt;/p&gt;
  &lt;pre id=&quot;1LmP&quot; data-lang=&quot;java&quot;&gt;// Интерфейс абстрактной фабрики убежищ
interface ShelterFactory {
    Wall createWall();
    Door createDoor();
    PowerSource createPowerSource();
}&lt;/pre&gt;
  &lt;p id=&quot;6zar&quot;&gt;И, наконец, создадим конкретные фабрики для каждого типа убежища:&lt;/p&gt;
  &lt;pre id=&quot;EkdY&quot; data-lang=&quot;java&quot;&gt;// Фабрика для создания убежища из хлама
class ScrapShelterFactory implements ShelterFactory {
    @Override
    public Wall createWall() {
        return new ScrapWall();
    }

    @Override
    public Door createDoor() {
        return new ScrapDoor();
    }

    @Override
    public PowerSource createPowerSource() {
        return new CarEngineGenerator();
    }
}

// Фабрика для создания военного бункера
class MilitaryBunkerFactory implements ShelterFactory {
    @Override
    public Wall createWall() {
        return new ReinforcedConcreteWall();
    }

    @Override
    public Door createDoor() {
        return new BlastDoor();
    }

    @Override
    public PowerSource createPowerSource() {
        return new MilitaryDieselGenerator();
    }
}&lt;/pre&gt;
  &lt;p id=&quot;D4Bw&quot;&gt;Теперь код, отвечающий за строительство, может получить нужную фабрику (например, на основе найденных чертежей) и построить цельное, совместимое убежище, не зная, из каких именно деталей оно состоит.&lt;/p&gt;
  &lt;h3 id=&quot;AtHD&quot;&gt;Шаги реализации&lt;/h3&gt;
  &lt;ol id=&quot;M60s&quot;&gt;
    &lt;li id=&quot;LBl0&quot;&gt;Создайте таблицу соотношений типов продуктов к вариациям семейств продуктов.&lt;/li&gt;
    &lt;li id=&quot;B4fv&quot;&gt;Сведите все вариации продуктов к общим интерфейсам.&lt;/li&gt;
    &lt;li id=&quot;Jq7Q&quot;&gt;Определите интерфейс абстрактной фабрики. Он должен иметь фабричные методы для создания каждого из типов продуктов.&lt;/li&gt;
    &lt;li id=&quot;Y3DU&quot;&gt;Создайте классы конкретных фабрик, реализовав интерфейс абстрактной фабрики. Этих классов должно быть столько же, сколько и вариаций семейств продуктов.&lt;/li&gt;
    &lt;li id=&quot;pazn&quot;&gt;Измените код инициализации программы так, чтобы она создавала определённую фабрику и передавала её в клиентский код.&lt;/li&gt;
    &lt;li id=&quot;CY0o&quot;&gt;Замените в клиентском коде участки создания продуктов через конструктор вызовами соответствующих методов фабрики.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;nyYx&quot;&gt;Вопросы&lt;/h2&gt;
  &lt;p id=&quot;mqIm&quot;&gt;&lt;strong&gt;1. В чем разница между Абстрактной фабрикой и Фабричным методом?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;RxQn&quot;&gt;&lt;strong&gt;Фабричный метод&lt;/strong&gt; — это один метод для создания &lt;strong&gt;одного&lt;/strong&gt; объекта. Решение о том, какой класс создавать, делегируется подклассам (наследование).&lt;/p&gt;
  &lt;p id=&quot;pLHW&quot;&gt;&lt;strong&gt;Абстрактная фабрика&lt;/strong&gt; — это интерфейс для создания &lt;strong&gt;семейства&lt;/strong&gt; взаимосвязанных объектов. Использует композицию: клиентский код работает с объектом фабрики.&lt;/p&gt;
  &lt;p id=&quot;BcSj&quot;&gt;&lt;strong&gt;Аналогия:&lt;/strong&gt; Фабричный метод — это станок, производящий один тип детали (гвозди). Абстрактная фабрика — это целый завод (например, «Ивановский мебельный завод»), который производит всё для комплекта мебели (столы, стулья, шкафы).&lt;/p&gt;
  &lt;ol id=&quot;5WYA&quot;&gt;
    &lt;ul id=&quot;ZAiI&quot;&gt;
      &lt;ul id=&quot;VuyR&quot;&gt;&lt;/ul&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;ubcl&quot;&gt;&lt;strong&gt;2. В чем разница между Абстрактной фабрикой и Строителем (Builder)?&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;fGwG&quot;&gt;&lt;strong&gt;Абстрактная фабрика&lt;/strong&gt; фокусируется на создании &lt;strong&gt;семейства объектов&lt;/strong&gt;. Продукты создаются и возвращаются сразу.&lt;/p&gt;
  &lt;p id=&quot;0rep&quot;&gt;&lt;strong&gt;Строитель&lt;/strong&gt; фокусируется на пошаговом создании &lt;strong&gt;одного сложного объекта&lt;/strong&gt;. Продукт возвращается только в конце, после вызова метода build().&lt;/p&gt;
  &lt;p id=&quot;QWUE&quot;&gt;&lt;strong&gt;Пример:&lt;/strong&gt; Абстрактная фабрика создаст вам сразу Двигатель, Кузов и Колеса для автомобиля Ford, в зависимости от выбранной реализации/семейства. Строитель будет по шагам собирать один сложный объект Дом, вызывая методы добавитьПотолок(), добавитьПол(), добавитьСтены(); вы можете выбирать части из разных семейств, постепенно создавая свой дом мечты &lt;/p&gt;
  &lt;p id=&quot;UIuA&quot;&gt;&lt;strong&gt;3. Назовите главный недостаток Абстрактной фабрики&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;Wbne&quot;&gt;Главный недостаток — &lt;strong&gt;сложность добавления нового типа продукта&lt;/strong&gt;. Если вы захотите добавить в семейство Лампу (к Креслу, Дивану, Столику), вам придётся изменить интерфейс Абстрактной Фабрики, а затем — все её конкретные реализации (ФабрикаАр-деко, ФабрикаМодерн и т.д.).&lt;/p&gt;
  &lt;h2 id=&quot;xDc5&quot;&gt;Задача&lt;/h2&gt;
  &lt;p id=&quot;XY2Z&quot;&gt;«Представьте, что у нас есть код, который напрямую создает объекты: new WindowsButton(), new WindowsCheckbox(). Проведите рефакторинг этого кода с использованием паттерна Абстрактная фабрика».&lt;/p&gt;
  &lt;ul id=&quot;wavF&quot;&gt;
    &lt;li id=&quot;yODN&quot;&gt;Создать интерфейсы Button, Checkbox.&lt;/li&gt;
    &lt;li id=&quot;OBd5&quot;&gt;Создать интерфейс GUIFactory с методами createButton() и createCheckbox().&lt;/li&gt;
    &lt;li id=&quot;UBX5&quot;&gt;Создать классы WindowsButton, WindowsCheckbox и WindowsFactory.&lt;/li&gt;
    &lt;li id=&quot;qIKP&quot;&gt;Создать классы MacButton, MacCheckbox и MacFactory.&lt;/li&gt;
    &lt;li id=&quot;FfoN&quot;&gt;В клиентском коде заменить new WindowsButton() на factory.createButton().&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ol id=&quot;BkEo&quot;&gt;
    &lt;ul id=&quot;jYev&quot;&gt;
      &lt;ol id=&quot;alLr&quot;&gt;&lt;/ol&gt;
    &lt;/ul&gt;
    &lt;ul id=&quot;vuez&quot;&gt;
      &lt;ul id=&quot;WhMB&quot;&gt;&lt;/ul&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;PlKu&quot;&gt;Ресурсы&lt;/h2&gt;
  &lt;p id=&quot;9WFM&quot;&gt;&lt;a href=&quot;https://refactoringguru.cn/ru/design-patterns/abstract-factory&quot; target=&quot;_blank&quot;&gt;Абстрактная фабрика&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>llax:rxzOiofXNRX</id><link rel="alternate" type="text/html" href="https://teletype.in/@llax/rxzOiofXNRX?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=llax"></link><title>Расширяем возможности Java с Google Guava: дополнительные коллекции, примеры использования</title><published>2024-08-05T09:40:28.180Z</published><updated>2024-08-05T09:42:50.489Z</updated><category term="java-core" label="Java Core"></category><summary type="html">Google Guava — это библиотека для Java, разработанная Google, которая предоставляет множество удобных утилит для работы с коллекциями, функциональным программированием, кэшированием, параллелизмом и другими аспектами разработки. В этой статье мы рассмотрим дополнительные реализации коллекций, предлагаемые Google Guava, приведем примеры их использования и покажем, как добавить библиотеку в проект.</summary><content type="html">
  &lt;h2 id=&quot;jN4e&quot;&gt;Введение&lt;/h2&gt;
  &lt;p id=&quot;LeCW&quot;&gt;Google Guava — это библиотека для Java, разработанная Google, которая предоставляет множество удобных утилит для работы с коллекциями, функциональным программированием, кэшированием, параллелизмом и другими аспектами разработки. В этой статье мы рассмотрим дополнительные реализации коллекций, предлагаемые Google Guava, приведем примеры их использования и покажем, как добавить библиотеку в проект.&lt;/p&gt;
  &lt;h2 id=&quot;4E0U&quot;&gt;Установка Google Guava в проект&lt;/h2&gt;
  &lt;p id=&quot;fm6m&quot;&gt;Для использования Google Guava в проекте необходимо добавить зависимость в файл конфигурации сборки. Инструкции для разных систем сборки можно найти на &lt;a href=&quot;https://github.com/google/guava&quot; target=&quot;_blank&quot;&gt;официальной странице Google Guava на GitHub&lt;/a&gt;.&lt;/p&gt;
  &lt;h3 id=&quot;H6ws&quot;&gt;Использование с Maven&lt;/h3&gt;
  &lt;p id=&quot;Kg5d&quot;&gt;Добавьте следующую зависимость в ваш &lt;code&gt;pom.xml&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;3wkN&quot; data-lang=&quot;css&quot;&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;com.google.guava&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;guava&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;32.1.2-jre&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/pre&gt;
  &lt;h3 id=&quot;2own&quot;&gt;Использование с Gradle&lt;/h3&gt;
  &lt;p id=&quot;NySA&quot;&gt;Добавьте следующую строку в ваш файл &lt;code&gt;build.gradle&lt;/code&gt;:&lt;/p&gt;
  &lt;pre id=&quot;h1ua&quot; data-lang=&quot;graphql&quot;&gt;implementation &amp;#x27;com.google.guava:guava:32.1.2-jre&amp;#x27;&lt;/pre&gt;
  &lt;h2 id=&quot;3YmA&quot;&gt;Основные Коллекции Google Guava&lt;/h2&gt;
  &lt;p id=&quot;sDo8&quot;&gt;Guava предоставляет несколько расширений стандартных коллекций Java, а также новые типы коллекций, которые упрощают и улучшают работу с данными. Вот некоторые из них:&lt;/p&gt;
  &lt;h3 id=&quot;qQU9&quot;&gt;Immutable Collections&lt;/h3&gt;
  &lt;p id=&quot;VLHK&quot;&gt;Неизменяемые коллекции гарантируют, что их содержимое не будет изменяться после создания. Это делает их потокобезопасными и может улучшить производительность, устраняя необходимость синхронизации.&lt;/p&gt;
  &lt;p id=&quot;XYJI&quot;&gt;&lt;strong&gt;Пример использования:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;5OuS&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.ImmutableList;

public class ImmutableExample {
    public static void main(String[] args) {
        ImmutableList&amp;lt;String&amp;gt; immutableList = ImmutableList.of(&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;);
        System.out.println(immutableList);
        
        // Any attempt to modify the list will throw UnsupportedOperationException
        // immutableList.add(&amp;quot;four&amp;quot;); // This will throw an exception
    }
}&lt;/pre&gt;
  &lt;h3 id=&quot;Wf5p&quot;&gt;Multiset&lt;/h3&gt;
  &lt;p id=&quot;CmvH&quot;&gt;Multiset — это коллекция, которая позволяет хранить дубликаты элементов и отслеживать количество их вхождений.&lt;/p&gt;
  &lt;p id=&quot;O2jA&quot;&gt;&lt;strong&gt;Пример использования:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;W96N&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;

public class MultisetExample {
    public static void main(String[] args) {
        Multiset&amp;lt;String&amp;gt; multiset = HashMultiset.create();
        multiset.add(&amp;quot;apple&amp;quot;);
        multiset.add(&amp;quot;banana&amp;quot;);
        multiset.add(&amp;quot;apple&amp;quot;);
        
        System.out.println(multiset.count(&amp;quot;apple&amp;quot;)); // Output: 2
        System.out.println(multiset.count(&amp;quot;banana&amp;quot;)); // Output: 1
        
    }
}&lt;/pre&gt;
  &lt;h3 id=&quot;9Pzw&quot;&gt;Multimap&lt;/h3&gt;
  &lt;p id=&quot;JI9C&quot;&gt;Multimap — это коллекция, которая позволяет хранить несколько значений для одного ключа.&lt;/p&gt;
  &lt;p id=&quot;VBda&quot;&gt;&lt;strong&gt;Пример использования:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;OKe0&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class MultimapExample {
    public static void main(String[] args) {
        Multimap&amp;lt;String, String&amp;gt; multimap = ArrayListMultimap.create();
        multimap.put(&amp;quot;fruit&amp;quot;, &amp;quot;apple&amp;quot;);
        multimap.put(&amp;quot;fruit&amp;quot;, &amp;quot;banana&amp;quot;);
        multimap.put(&amp;quot;vegetable&amp;quot;, &amp;quot;carrot&amp;quot;);
        
        System.out.println(multimap.get(&amp;quot;fruit&amp;quot;)); // Output: [apple, banana]
        System.out.println(multimap.get(&amp;quot;vegetable&amp;quot;)); // Output: [carrot]
    }
}
&lt;/pre&gt;
  &lt;h3 id=&quot;ehlQ&quot;&gt;BiMap&lt;/h3&gt;
  &lt;p id=&quot;kwCm&quot;&gt;BiMap — это двухсторонняя карта, которая позволяет уникальные соответствия между ключами и значениями. Это означает, что вы можете выполнять обратный поиск по значениям, как и по ключам.&lt;/p&gt;
  &lt;p id=&quot;yQgB&quot;&gt;&lt;strong&gt;Пример использования:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;X8QN&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.HashBiMap;
import com.google.common.collect.BiMap;

public class BiMapExample {
    public static void main(String[] args) {
        BiMap&amp;lt;String, Integer&amp;gt; biMap = HashBiMap.create();
        biMap.put(&amp;quot;one&amp;quot;, 1);
        biMap.put(&amp;quot;two&amp;quot;, 2);
        
        System.out.println(biMap.get(&amp;quot;one&amp;quot;)); // Output: 1
        System.out.println(biMap.inverse().get(1)); // Output: one
    }
}
&lt;/pre&gt;
  &lt;h3 id=&quot;EZfM&quot;&gt;Table&lt;/h3&gt;
  &lt;p id=&quot;qqIq&quot;&gt;Table представляет собой двумерную карту, аналогичную Map&amp;lt;R, Map&amp;lt;C, V&amp;gt;&amp;gt;.&lt;/p&gt;
  &lt;p id=&quot;Qfio&quot;&gt;&lt;strong&gt;Пример использования:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;4kqI&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;

public class TableExample {
    public static void main(String[] args) {
        Table&amp;lt;String, String, Integer&amp;gt; table = HashBasedTable.create();
        table.put(&amp;quot;row1&amp;quot;, &amp;quot;col1&amp;quot;, 1);
        table.put(&amp;quot;row1&amp;quot;, &amp;quot;col2&amp;quot;, 2);
        table.put(&amp;quot;row2&amp;quot;, &amp;quot;col1&amp;quot;, 3);
        
        System.out.println(table.get(&amp;quot;row1&amp;quot;, &amp;quot;col1&amp;quot;)); // Output: 1
        System.out.println(table.row(&amp;quot;row1&amp;quot;)); // Output: {col1=1, col2=2}
        System.out.println(table.column(&amp;quot;col1&amp;quot;)); // Output: {row1=1, row2=3}
    }
}
&lt;/pre&gt;
  &lt;h3 id=&quot;4N2v&quot;&gt;RangeSet и RangeMap&lt;/h3&gt;
  &lt;p id=&quot;V0wQ&quot;&gt;RangeSet и RangeMap предоставляют удобные способы работы с диапазонами чисел и ассоциациями диапазонов с объектами.&lt;/p&gt;
  &lt;p id=&quot;yg88&quot;&gt;&lt;strong&gt;Пример использования RangeSet:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;xE4W&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.Range;
import com.google.common.collect.TreeRangeSet;
import com.google.common.collect.RangeSet;

public class RangeSetExample {
    public static void main(String[] args) {
        RangeSet&amp;lt;Integer&amp;gt; rangeSet = TreeRangeSet.create();
        rangeSet.add(Range.closed(1, 10));
        rangeSet.add(Range.closed(20, 30));
        
        System.out.println(rangeSet.contains(5)); // Output: true
        System.out.println(rangeSet.contains(15)); // Output: false
    }
}
&lt;/pre&gt;
  &lt;p id=&quot;dLW1&quot;&gt;Пример использования RangeMap:&lt;/p&gt;
  &lt;pre id=&quot;fT4s&quot; data-lang=&quot;java&quot;&gt;import com.google.common.collect.Range;
import com.google.common.collect.TreeRangeMap;
import com.google.common.collect.RangeMap;

public class RangeMapExample {
    public static void main(String[] args) {
        RangeMap&amp;lt;Integer, String&amp;gt; rangeMap = TreeRangeMap.create();
        rangeMap.put(Range.closed(1, 10), &amp;quot;Low&amp;quot;);
        rangeMap.put(Range.closed(11, 20), &amp;quot;Medium&amp;quot;);
        
        System.out.println(rangeMap.get(5)); // Output: Low
        System.out.println(rangeMap.get(15)); // Output: Medium
    }
}
&lt;/pre&gt;
  &lt;h2 id=&quot;2VcA&quot;&gt;Заключение&lt;/h2&gt;
  &lt;p id=&quot;tJln&quot;&gt;Google Guava предоставляет множество дополнительных коллекций, которые значительно расширяют возможности стандартных коллекций Java. Использование этих коллекций может упростить разработку, повысить производительность и улучшить читаемость кода. В этой статье мы рассмотрели основные из них, включая неизменяемые коллекции, Multiset, Multimap, BiMap, Table, RangeSet и RangeMap, и привели примеры их использования. Изучение и использование этих коллекций поможет вам создавать более эффективные и надежные приложения на Java.&lt;/p&gt;
  &lt;p id=&quot;uRAy&quot;&gt;Google Guava делает вашу работу с коллекциями более выразительной и удобной, предоставляя множество дополнительных инструментов и возможностей. Попробуйте использовать эти коллекции в своих проектах и убедитесь в их преимуществах сами.&lt;/p&gt;

</content></entry></feed>