Skip to content

Instantly share code, notes, and snippets.

@Shtaba09
Created April 11, 2020 23:53
Show Gist options
  • Save Shtaba09/befef3166278c96925d13c3282972bc4 to your computer and use it in GitHub Desktop.
Save Shtaba09/befef3166278c96925d13c3282972bc4 to your computer and use it in GitHub Desktop.
Shortner Зделать еще JDBC
package com.javarush.task.task33.task3310;
public class ExceptionHandler {
public static void log(Exception e){
System.out.println(e.getLocalizedMessage());
}
}
package com.javarush.task.task33.task3310;
import java.math.BigInteger;
import java.security.SecureRandom;
public class Helper {
public static String generateRandomString() {
return new BigInteger(130, new SecureRandom()).toString(36);
}
public static void printMessage(String message){
System.out.println(message);
}
}
package com.javarush.task.task33.task3310;
import com.javarush.task.task33.task3310.strategy.StorageStrategy;
public class Shortener {
private Long lastId=0L;
private StorageStrategy storageStrategy;
public Shortener(StorageStrategy storageStrategy) {
this.storageStrategy = storageStrategy;
}
public synchronized Long getId(String string){
if (storageStrategy.containsValue(string)){
return storageStrategy.getKey(string);
}else {
lastId++;
storageStrategy.put(lastId,string);
return lastId;
}
}
public synchronized String getString(Long id){
return storageStrategy.getValue(id);
}
}
package com.javarush.task.task33.task3310;
import com.javarush.task.task33.task3310.strategy.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Solution {
public static void main(String[] args){
HashMapStorageStrategy strategy = new HashMapStorageStrategy();
OurHashMapStorageStrategy strategy1 = new OurHashMapStorageStrategy();
FileStorageStrategy strategy2 = new FileStorageStrategy();
OurHashBiMapStorageStrategy strategy3 = new OurHashBiMapStorageStrategy();
HashBiMapStorageStrategy strategy4 = new HashBiMapStorageStrategy();
DualHashBidiMapStorageStrategy strategy5 = new DualHashBidiMapStorageStrategy();
testStrategy(strategy,10000L);
testStrategy(strategy1,10000L);
// testStrategy(strategy2,2000L);
testStrategy(strategy3,10000L);
testStrategy(strategy4,10000L);
testStrategy(strategy5,10000L);
}
public static Set<Long> getIds(Shortener shortener, Set<String> strings){
Set<Long> ids = new HashSet<>();
for(String str : strings){
ids.add(shortener.getId(str));
}
return ids;
}
public static Set<String> getStrings(Shortener shortener, Set<Long> keys){
Set<String> strings = new HashSet<>();
for(Long key : keys){
strings.add(shortener.getString(key));
}
return strings;
}
public static void testStrategy(StorageStrategy strategy, long elementsNumber){
Helper.printMessage(strategy.getClass().getSimpleName());
Set<String> strings = new HashSet<>();
for(long i = 0L; i<elementsNumber; i++){
strings.add(Helper.generateRandomString());
}
Shortener shortener= new Shortener(strategy);
Date start = new Date();
Set<Long> ids = getIds(shortener,strings);
Date stop = new Date();
Long time = stop.getTime()-start.getTime();
Helper.printMessage(time.toString());
start = new Date();
Set<String> strings1 = getStrings(shortener,ids);
stop = new Date();
time = stop.getTime()-start.getTime();
Helper.printMessage(time.toString());
if(strings.containsAll(strings1)){
Helper.printMessage("Тест пройден.");
} else { Helper.printMessage("Тест не пройден.");}
}
}
package com.javarush.task.task33.task3310.strategy;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
public class DualHashBidiMapStorageStrategy implements StorageStrategy {
private DualHashBidiMap data = new DualHashBidiMap();
@Override
public boolean containsKey(Long key) {
return data.containsKey(key);
}
@Override
public boolean containsValue(String value) {
return data.containsValue(value);
}
@Override
public void put(Long key, String value) {
data.put(key,value);
}
@Override
public Long getKey(String value) {
return (Long) data.getKey(value);
}
@Override
public String getValue(Long key) {
return (String) data.get(key);
}
}
package com.javarush.task.task33.task3310.strategy;
import java.io.Serializable;
import java.util.Objects;
public class Entry implements Serializable {
Long key;
String value;
Entry next;
int hash;
public Entry(int hash, Long key, String value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
this.hash = hash;
}
public Long getKey(){
return key;
}
public String getValue(){
return value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Entry entry = (Entry) o;
return Objects.equals(key, entry.key) &&
Objects.equals(value, entry.value);
}
@Override
public int hashCode() {
return Objects.hash(key, value);
}
@Override
public String toString() {
return key+"="+value;
}
}
package com.javarush.task.task33.task3310.strategy;
import com.fasterxml.jackson.databind.ObjectWriter;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
public class FileBucket {
Path path ;
public FileBucket() {
try {
path= Files.createTempFile(null,null);
Files.deleteIfExists(path);
Files.createFile(path);
path.toFile().deleteOnExit();
} catch (IOException e) {
//ignored
}
}
public long getFileSize() {
try {
return Files.size(path);
} catch (IOException e) {
return 0L;
}
}
public void putEntry(Entry entry){
try {
ObjectOutputStream objectWriter = new ObjectOutputStream(Files.newOutputStream(path));
objectWriter.writeObject(entry);
objectWriter.flush();
objectWriter.close();
} catch (IOException e) {
//ign
}
}
public Entry getEntry(){
if(getFileSize()==0L)return null;
try {
ObjectInputStream objectReader = new ObjectInputStream(Files.newInputStream(path));
Entry entry= (Entry)objectReader.readObject();
objectReader.close();
return entry;
} catch (IOException | ClassNotFoundException e) { }
return null;
}
public void remove(){
try {
Files.delete(path);
} catch (IOException e) {
}
}
}
package com.javarush.task.task33.task3310.strategy;
public class FileStorageStrategy implements StorageStrategy{
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final long DEFAULT_BUCKET_SIZE_LIMIT = 10000L;
FileBucket[] table = new FileBucket[DEFAULT_INITIAL_CAPACITY];
private long bucketSizeLimit = DEFAULT_BUCKET_SIZE_LIMIT;
long maxBucketSize;
int size;
public long getBucketSizeLimit() {
return bucketSizeLimit;
}
public void setBucketSizeLimit(long bucketSizeLimit) {
this.bucketSizeLimit = bucketSizeLimit;
}
public int hash(Long k){
int h=Integer.parseInt(k.toString());
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
public int indexFor(int hash, int length){
return hash & (length - 1);
}
public Entry getEntry(Long key){
int hash = (key == null) ? 0 : hash(key);
for (Entry e = table[indexFor(hash, table.length)].getEntry();
e != null;
e = e.next) {
Long k;
if (e.hash == hash && ((k = e.key).equals(key) || (key != null && key.equals(k))))
return e;
}
return null;
}
public FileStorageStrategy() {
table = new FileBucket[DEFAULT_INITIAL_CAPACITY];
for(int i = 0; i < table.length; ++i)
table[i] = new FileBucket();
}
public void resize(int newCapacity){
FileBucket[] newTable = new FileBucket[newCapacity];
for (FileBucket fileBucket : newTable)
fileBucket = new FileBucket();
transfer(newTable);
table = newTable;
}
public void transfer(FileBucket[] newTable) {
int newCapacity = newTable.length;
for (int i = 0; i < table.length; i++) {
if (table[i] == null) continue;
Entry entry = table[i].getEntry();
while (entry != null) {
Entry next = entry.next;
int indexFor = indexFor(entry.hash, newCapacity);
entry.next = newTable[indexFor].getEntry();
newTable[indexFor].putEntry(entry);
entry = next;
}
table[i].remove();
table[i] = null;
}
}
public void addEntry(int hash, Long key, String value, int bucketIndex) {
Entry entry = table[bucketIndex].getEntry();
table[bucketIndex].putEntry(new Entry(hash, key, value, entry));
size++;
if(table[bucketIndex].getFileSize() > bucketSizeLimit) {
resize(2 * table.length); }
}
public void createEntry(int hash, Long key, String value, int bucketIndex) {
table[bucketIndex] = new FileBucket();
table[bucketIndex].putEntry(new Entry(hash, key, value, null));
size++;
}
@Override
public boolean containsKey(Long key) {
return getEntry(key) != null;
}
@Override
public boolean containsValue(String value) {
if (value == null){return false;}
for (int i = 0; i < table.length ; i++)
if (table[i] != null) {
for (Entry e = table[i].getEntry(); e != null ; e = e.next)
if (value.equals(e.value))
return true;}
return false;
}
@Override
public void put(Long key, String value) {
int hash = hash(key);
int i = indexFor(hash, table.length);
if (table[i] == null)
createEntry(hash, key, value, i);
else {
for (Entry entry = table[i].getEntry(); entry != null; entry = entry.next) {
Long k;
if (entry.hash == hash && ((k = entry.key) == key || key.equals(k)))
entry.value = value;
}
addEntry(hash, key, value, i);
}
}
@Override
public Long getKey(String value) {
for (int i = 0; i < table.length ; i++) {
if (table[i] == null) continue;
for (Entry e = table[i].getEntry(); e != null; e = e.next)
if (value.equals(e.value))
return e.key;
}
return null;
}
@Override
public String getValue(Long key) {
return getEntry(key).getValue();
}
}
package com.javarush.task.task33.task3310.strategy;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
public class HashBiMapStorageStrategy implements StorageStrategy {
private HashBiMap data = HashBiMap.create() ;
@Override
public boolean containsKey(Long key) {
return data.containsKey(key);
}
@Override
public boolean containsValue(String value) {
return data.containsValue(value);
}
@Override
public void put(Long key, String value) {
data.put(key,value);
}
@Override
public Long getKey(String value) {
BiMap copy = data.inverse();
return (Long) copy.get(value);
}
@Override
public String getValue(Long key) {
return (String) data.get(key);
}
}
package com.javarush.task.task33.task3310.strategy;
import java.util.HashMap;
import java.util.Map;
public class HashMapStorageStrategy implements StorageStrategy {
private HashMap<Long, String> data = new HashMap<>();
@Override
public boolean containsKey(Long key) {
return data.containsKey(key);
}
@Override
public boolean containsValue(String value) {
return data.containsValue(value);
}
@Override
public void put(Long key, String value) {
data.put(key,value);
}
@Override
public Long getKey(String value) {
for (Map.Entry<Long,String> pair : data.entrySet()){
if(value.contains(pair.getValue())){
return pair.getKey();
}
}
return null;
}
@Override
public String getValue(Long key) {
return data.get(key);
}
}
package com.javarush.task.task33.task3310.strategy;
import java.util.HashMap;
public class OurHashBiMapStorageStrategy implements StorageStrategy {
private HashMap<Long, String> k2v = new HashMap<>();
private HashMap<String, Long> v2k = new HashMap<>();
@Override
public boolean containsKey(Long key) {
return k2v.containsKey(key);
}
@Override
public boolean containsValue(String value) {
return v2k.containsKey(value);
}
@Override
public void put(Long key, String value) {
k2v.put(key,value);
v2k.put(value,key);
}
@Override
public Long getKey(String value) {
return v2k.get(value);
}
@Override
public String getValue(Long key) {
return k2v.get(key);
}
}
package com.javarush.task.task33.task3310.strategy;
public class OurHashMapStorageStrategy implements StorageStrategy {
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
Entry[] table = new Entry[DEFAULT_INITIAL_CAPACITY];
int size;
int threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
float loadFactor = DEFAULT_LOAD_FACTOR;
public int hash(Long k){
int h=Integer.parseInt(k.toString());
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
public int indexFor(int hash, int length){
return hash & (length - 1);
}
public Entry getEntry(Long key){
int hash = (key == null) ? 0 : hash(key);
for (Entry e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
public void resize(int newCapacity){
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}
public void transfer(Entry[] newTable) {
Entry[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry e = src[j];
if (e != null) {
src[j] = null;
do {
Entry next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
public void addEntry(int hash, Long key, String value, int bucketIndex){
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
public void createEntry(int hash, Long key, String value, int bucketIndex){
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry(hash, key, value, e);
size++;
}
@Override
public boolean containsKey(Long key) {
for(Entry entry : table){
if (entry.getKey().equals(key)){return true;}
}
return false;
}
@Override
public boolean containsValue(String value) {
if (value == null){return false;}
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}
@Override
public void put(Long key, String value) {
int hash = hash(key);
createEntry(hash,key,value,indexFor(hash,table.length));
}
@Override
public Long getKey(String value) {
for(Entry entry : table){
if(entry!=null) {
if (entry.value.equals(value)) {
return entry.getKey();
}
}
}
return null;
}
@Override
public String getValue(Long key) {
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (key.equals(e.key))
return e.getValue();
return null;
}
}
package com.javarush.task.task33.task3310.strategy;
public interface StorageStrategy {
public boolean containsKey(Long key);
public boolean containsValue(String value);
public void put(Long key, String value);
public Long getKey(String value);
public String getValue(Long key);
}
package com.javarush.task.task33.task3310.tests;
import com.javarush.task.task33.task3310.Shortener;
import com.javarush.task.task33.task3310.strategy.*;
import org.junit.Assert;
import org.junit.Test;
public class FunctionalTest {
public void testStorage(Shortener shortener){
String one = "TestThis";
String two = "NotThis";
String three = "TestThis";
Long idOne = shortener.getId(one);
Long idTwo = shortener.getId(two);
Long idThree = shortener.getId(three);
Assert.assertNotEquals("idTwo equalsh 1",idTwo,idOne);
Assert.assertNotEquals("idTwo equalsh 3",idTwo,idThree);
Assert.assertEquals("id1 not equals id3 ",idOne,idThree);
String oneTest =shortener.getString(idOne);
String twoTest = shortener.getString(idTwo);
String threeTest= shortener.getString(idThree);
Assert.assertEquals("String one fail",one,oneTest);
Assert.assertEquals("String two fail",two,twoTest);
Assert.assertEquals("String three fail",three,threeTest);
}
@Test
public void testHashMapStorageStrategy(){
Shortener shortener = new Shortener(new HashMapStorageStrategy());
testStorage(shortener);
}
@Test
public void testOurHashMapStorageStrategy(){
Shortener shortener = new Shortener(new OurHashMapStorageStrategy());
testStorage(shortener);
}
@Test
public void testFileStorageStrategy(){
Shortener shortener = new Shortener(new FileStorageStrategy());
testStorage(shortener);
}
@Test
public void testHashBiMapStorageStrategy(){
Shortener shortener = new Shortener(new HashBiMapStorageStrategy());
testStorage(shortener);
}
@Test
public void testDualHashBidiMapStorageStrategy(){
Shortener shortener = new Shortener(new DualHashBidiMapStorageStrategy());
testStorage(shortener);
}
@Test
public void testOurHashBiMapStorageStrategy(){
Shortener shortener = new Shortener(new OurHashBiMapStorageStrategy());
testStorage(shortener);
}
}
package com.javarush.task.task33.task3310.tests;
import com.javarush.task.task33.task3310.Helper;
import com.javarush.task.task33.task3310.Shortener;
import com.javarush.task.task33.task3310.strategy.HashBiMapStorageStrategy;
import com.javarush.task.task33.task3310.strategy.HashMapStorageStrategy;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class SpeedTest {
public long getTimeToGetIds(Shortener shortener, Set<String> strings, Set<Long> ids){
Date start = new Date();
for(String str :strings){
ids.add(shortener.getId(str));
}
Date stop = new Date();
return stop.getTime()-start.getTime();
}
public long getTimeToGetStrings(Shortener shortener, Set<Long> ids, Set<String> strings){
Date start = new Date();
for(Long id :ids){
strings.add(shortener.getString(id));
}
Date stop = new Date();
return stop.getTime()-start.getTime();
}
@Test
public void testHashMapStorage(){
Shortener shortener1 = new Shortener(new HashMapStorageStrategy());
Shortener shortener2 = new Shortener(new HashBiMapStorageStrategy());
Set<String> origStrings = new HashSet<>();
Set<Long> ids1 = new HashSet<>();
Set<Long> ids2 = new HashSet<>();
for (int i=0;i<10000; i++){
origStrings.add(Helper.generateRandomString());
}
Long time1 = getTimeToGetIds(shortener1,origStrings,ids1);
Long time2 = getTimeToGetIds(shortener2,origStrings,ids2);
Assert.assertTrue((time1>time2));
time1 = getTimeToGetStrings(shortener1,ids1,new HashSet<>());
time2 = getTimeToGetStrings(shortener2,ids2,new HashSet<>());
Assert.assertEquals(time1,time2,30);
}
}
taskKey="com.javarush.task.task33.task3310.big16"\n\nShortener (16)
Что можешь сделать самостоятельно (тестов на этот пункт нет):
- Добавить стратегию, основанную на работе с базой данных. Гугли JDBC.
- Сделать веб сервис, который будет для любого url или строки возвращать
идентификатор, а для идентификатора строку.
- Написать вариант HashMap с использованием двух потоков, где один поток будет
отвечать за работу с элементами, а второй следить за количеством элементов. Когда
количество элементов превысит порог threshold, второй поток должен увеличить
размер table в 2 раза. При этом, первый поток ничего не должен знать о пороге.
Твои достижения:
- Повторил паттерн Стратегия.
- Получил опыт работы с библиотекой Guava.
- Получил опыт работы с Apache Commons Collections.
- Попробовал писать тесты, используя Junit.
- Еще на шаг продвинулся к работе Java программистом.
Поздравляю! Я горжусь тобой!
Ты отличный ученик!
Требования:
1. Shortener готов!
Shortener (15)
Напишем еще один тест, который проверит, что получить идентификатор для строки
используя стратегию HashBiMapStorageStrategy можно быстрее, чем используя
стратегию HashMapStorageStrategy.
15.1. Создай класс SpeedTest в пакете tests.
15.2. Добавь в класс метод long getTimeToGetIds(Shortener shortener, Set<String>
strings, Set<Long> ids). Он должен возвращать время в миллисекундах необходимое
для получения идентификаторов для всех строк из strings. Идентификаторы
должны быть записаны в ids.
15.3. Добавь в класс метод long getTimeToGetStrings(Shortener shortener,
Set<Long> ids, Set<String> strings). Он должен возвращать время в миллисекундах
необходимое для получения строк для всех идентификаторов из ids. Строки
должны быть записаны в strings.
15.4. Добавь в класс SpeedTest тест testHashMapStorage(). Он должен:
15.4.1. Создавать два объекта типа Shortener, один на базе
HashMapStorageStrategy, второй на базе HashBiMapStorageStrategy. Назовем
их shortener1 и shortener2.
15.4.2. Генерировать с помощью Helper 10000 строк и помещать их в сет со
строками, назовем его origStrings.
15.4.3. Получать время получения идентификаторов для origStrings (вызывать
метод getTimeToGetIds для shortener1, а затем для shortener2).
15.4.4. Проверять с помощью junit, что время, полученное в предыдущем пункте
для shortener1 больше, чем для shortener2.
15.4.5. Получать время получения строк (вызывать метод getTimeToGetStrings
для shortener1 и shortener2).
15.4.6. Проверять с помощью junit, что время, полученное в предыдущем пункте
для shortener1 примерно равно времени для shortener2. Используй метод
assertEquals(float expected, float actual, float delta). В качестве delta можно
использовать 30, этого вполне достаточно для наших экспериментов.
Shortener (14)
Мы много раз тестировали наши стратегии с помощью метода testStrategy() класса
Solution. Пришло время написать настоящие юнит тесты с использованием junit.
14.1. Прочитай что такое юнит тесты.
14.2. Скачай и подключи библиотеку Junit 4.12. Разберись как ей пользоваться.
Библиотека Junit зависит от библиотеки hamcrest-core. Подключи и ее. Используй версию 1.3.
14.3. Добавь класс FunctionalTest в пакет tests. В этом классе мы проверим
функциональность наших стратегий.
14.4. Добавь в класс FunctionalTest метод testStorage(Shortener shortener). Он
должен:
14.4.1. Создавать три строки. Текст 1 и 3 строк должен быть одинаковым.
14.4.2. Получать и сохранять идентификаторы для всех трех строк с помощью
shortener.
14.4.3. Проверять, что идентификатор для 2 строки не равен идентификатору для 1
и 3 строк. Подсказка: метод Assert.assertNotEquals.
14.4.4. Проверять, что идентификаторы для 1 и 3 строк равны. Подсказка: метод
Assert.assertEquals.
14.4.5. Получать три строки по трем идентификаторам с помощью shortener.
14.4.6. Проверять, что строки, полученные в предыдущем пункте, эквивалентны
оригинальным. Подсказка: метод Assert.assertEquals.
14.5. Добавь в класс FunctionalTest тесты:
14.5.1. testHashMapStorageStrategy()
14.5.2. testOurHashMapStorageStrategy()
14.5.3. testFileStorageStrategy()
14.5.4. testHashBiMapStorageStrategy()
14.5.5. testDualHashBidiMapStorageStrategy()
14.5.6. testOurHashBiMapStorageStrategy()
Каждый тест должен иметь аннотацию @Test, создавать подходящую стратегию,
создавать объект класса Shortener на базе этой стратегии и вызывать метод
testStorage для него.
Запусти и проверь, что все тесты проходят.
Shortener (13)
Рассмотрим еще одну реализацию BiMap, на этот раз из Apache Commons Collections.
13.1. Скачай и подключи Apache Commons Collections 4.0.
13.2. Реализуй стратегию DualHashBidiMapStorageStrategy. Она должна:
13.2.1. Поддерживать интерфейс StorageStrategy.
13.2.2. Внутри иметь только одно поле data с типом DualHashBidiMap.
13.3. Проверь новую стратегию в методе main(). Запусти программу и сравни
скорость работы шести стратегий.
Shortener (12)
Задача, когда требуется создать Map, работающий в две стороны (по ключу получать
значение, а по значению ключ) не такая уж и редкая. Такие коллекции уже
реализованы в различных сторонних библиотеках коллекций. Одна из таких Guava от
Google.
12.1. Скачай и подключи библиотеку guava версии 19.0.
12.2. Реализуй стратегию HashBiMapStorageStrategy. Она должна:
12.2.1. Поддерживать интерфейс StorageStrategy.
12.2.2. Внутри иметь только одно поле data типа HashBiMap.
12.3. Проверь новую стратегию в методе main(). Запусти программу и сравни
скорость работы пяти стратегий.
Shortener (11)
Как ты заметил, получение идентификатора для строки требует намного больше
времени, чем получение строки по идентификатору. Это ожидаемо и следует из
реализации HashMap. Давай напишем четвертую стратегию
OurHashBiMapStorageStrategy, которая будет лишена этого недостатка.
11.1. Создай класс OurHashBiMapStorageStrategy, реализующий интерфейс
StorageStrategy.
11.2. Добавь в него два поля HashMap<Long, String> k2v и HashMap<String, Long> v2k.
Первое будет хранить соответствие ключа и значения, а второе наоборот: значения
и ключа.
11.3. Реализуй методы интерфейса StorageStrategy, обеспечив максимальную
скорость. Подсказка: при добавлении новой пары ключ-значение необходимо
добавлять ее сразу в два поля.
Проверь новую стратегию в методе main(). Запусти программу и сравни скорость работы
всех 4х стратегий. Убедись, что мы значительно увеличили скорость получения
идентификатора. Но как ты понимаешь, у этого решения есть не только плюсы, но и минусы.
Подумай в каких случаях имеет смысл использовать OurHashBiMapStorageStrategy, а в каких
HashMapStorageStrategy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment