Курс Java Collections — Лекция: Как сделать укорачиватель ссылок

— Привет, Амиго!

— Здравия желаю, Капитан Бобров!

— У тебя сегодня новая секретная миссия. Для того, чтобы переписка между нашими подразделениями была зашифрованной, тебе нужно реализовать свой сервис коротких ссылок.

— Круто. То есть я хотел сказать, я готов, сэр. Но зачем нам это нужно?

— Как это зачем? Боец, кругом враги, нам нужно защитить канал связи. Приступай к задаче.

— Есть, реализовать сервис коротких ссылок.

— Отправляйся к нашему секретному агенту Intellij IDEA, там получишь все инструкции.

— Будет сделано, товарищ капитан!

— Приступайте.

undefined

Shortener (1)

Давай напишем укорачиватель Shortener. Это будет некий аналог укорачивателя ссылок Google URL Shortener (https://goo.gl), но мы расширим его функциональность и сделаем консольным. Он будет сокращать не только ссылки, но и любые строки. Наш Shortener – это класс, который может для любой строки вернут

undefined

Shortener (2)

Укорачиватель Shortener будет поддерживать разные стратегии хранения данных (строк и их идентификаторов). Все эти стратегии будут наследоваться от интерфейса StorageStrategy. Почитай подробнее про паттерн Стратегия на Вики. Наше хранилище будет оперировать двумя понятиями: ключ и значение. Ключом бу

undefined

Shortener (3)

Вернемся к классу Shortener: 3.1. Добавь в него поле Long lastId. Проинициализируй его нулем. Это поле будет отвечать за последнее значение идентификатора, которое было использовано при добавлении новой строки в хранилище. 3.2. Добавь поле StorageStrategy storageStrategy в котором будет храниться ст

undefined

Shortener (4)

Нам потребуется несколько вспомогательных классов: 4.1. Создай класс Helper. 4.1.1. Добавь в него статический публичный метод String generateRandomString(), который будет генерировать случайную строку. Воспользуйся для этого классами SecureRandom и BigInteger. Подсказка: гугли запрос «random string java».

undefined

Shortener (5)

Давай напишем наше первое хранилище (стратегию хранилища). Внутри оно будет содержать обычный HashMap. Все стратегии будем хранить в пакете strategy. 5.1. Создай класс HashMapStorageStrategy, реализующий интерфейс StorageStrategy. 5.2. Добавь в класс поле HashMap<Long, String> data. В нем будут хран

undefined

Shortener (6)

Первая стратегия готова, пришло время ее протестить. Для этого: 6.1. Создай класс Solution, если ты не сделал это раньше. 6.2. Добавь в класс Solution реализации вспомогательных статических методов: 6.2.1. Set<Long> getIds(Shortener shortener, Set<String> strings). Этот метод должен для переданного

undefined

Shortener (7)

Приступим к реализации второй стратегии OurHashMapStorageStrategy. Она не будет использовать готовый HashMap из стандартной библиотеки, а будет сама являться коллекцией. 7.1. Разберись как работает стандартный HashMap, посмотри его исходники или погугли статьи на эту тему. 7.2. Если ты честно выпол

undefined

Shortener (8)

Добавь и реализуй класс OurHashMapStorageStrategy, используя класс Entry из предыдущей подзадачи. Класс OurHashMapStorageStrategy должен реализовывать интерфейс StorageStrategy. 8.1. Добавь в класс следующие поля: 8.1.1. static final int DEFAULT_INITIAL_CAPACITY = 16; 8.1.2. static final float DEFAU

undefined

Shortener (9)

Напишем еще одну стратегию, назовем ее FileStorageStrategy. Она будет очень похожа на стратегию OurHashMapStorageStrategy, но в качестве ведер (англ. buckets) будут файлы. Я знаю, ты знаешь о каких buckets идет речь, если нет – повтори внутреннее устройство HashMap. 9.1. Создай класс FileBucket в па

undefined

Shortener (10)

Создай и реализуй класс FileStorageStrategy. Он должен: 10.1. Реализовывать интерфейс StorageStrategy. 10.2. Использовать FileBucket в качестве ведер (англ. bucket). Подсказка: класс должен содержать поле FileBucket[] table. 10.3. Работать аналогично тому, как это делает OurHashMapStorageStrategy, н

undefined

Shortener (11)

Как ты заметил, получение идентификатора для строки требует намного больше времени, чем получение строки по идентификатору.

Это ожидаемо и следует из реализации HashMap. Давай напишем четвертую стратегию OurHashBiMapStorageStrategy, которая будет лишена этого недостатка. 11.1. Создай класс OurHashBi

undefined

Shortener (12)

Задача, когда требуется создать Map, работающий в две стороны (по ключу получать значение, а по значению ключ) не такая уж и редкая. Такие коллекции уже реализованы в различных сторонних библиотеках коллекций. Одна из таких Guava от Google. 12.1. Скачай и подключи библиотеку guava версии 19.0. 12.2.

undefined

Shortener (13)

Рассмотрим еще одну реализацию BiMap, на этот раз из Apache Commons Collections. 13.1. Скачай и подключи Apache Commons Collections 4.0. 13.2. Реализуй стратегию DualHashBidiMapStorageStrategy. Она должна: 13.2.1. Поддерживать интерфейс StorageStrategy. 13.2.2. Внутри иметь только одно поле data с т

undefined

Shortener (14)

Мы много раз тестировали наши стратегии с помощью метода testStrategy() класса Solution. Пришло время написать настоящие юнит тесты с использованием junit. 14.1. Прочитай что такое юнит тесты. 14.2. Скачай и подключи библиотеку Junit 4.12. Разберись как ей пользоваться. Библиотека Junit зависит от б

undefined

Shortener (15)

Напишем еще один тест, который проверит, что получить идентификатор для строки используя стратегию HashBiMapStorageStrategy можно быстрее, чем используя стратегию HashMapStorageStrategy. 15.1. Создай класс SpeedTest в пакете tests. 15.2. Добавь в класс метод long getTimeToGetIds(Shortener short

undefined

Shortener (16)

Что можешь сделать самостоятельно (тестов на этот пункт нет): — Добавить стратегию, основанную на работе с базой данных. Гугли JDBC. — Сделать веб сервис, который будет для любого url или строки возвращать идентификатор, а для идентификатора строку. — Написать вариант HashMap с использованием двух п

Лучший сокращатель ссылок со статистикой в 2022 году

Рейтинг сокращателей ссылок за Ноябрь 2022 года

1

Рейтинг 5 из 5

TinySRC