Вопрос о дизайне Java-кеша - PullRequest
       4

Вопрос о дизайне Java-кеша

0 голосов
/ 22 февраля 2011

Мне нужно разработать простой кэш (не требуется параллелизм или обновление) для хранения различных типов объектов. Поиск этих объектов может быть другим способом. Например, допустим, мы кешируем объект книги, который имеет номер ISBN и автора. Поиск этого объекта может быть либо по номеру ISBN, например

Поиск книг BookByISBN (String isbn);

ИЛИ это может быть поиск Автор, как

Список поиска BookByAuthor (String authorName);

Очень просто, это означает, что у меня может быть объект Cache, который имеет две карты: одну для хранения объекта книги по ISBN, а другую для хранения того же объекта по имени автора.

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

Один из способов, которым я думал о том, чтобы иметь одну Карту, ключом которой является пользовательский объект Key, а значением является Object (чтобы я мог сохранить любой объект или список объектов). Объект Key является неизменным объектом, который может выглядеть следующим образом

public class Key {   
      private final Stirng keyName;   
      private final String keyValue;   
      public Key(String name,String value) {
          this.keyName= name;
          this.keyValue = value;   
      }    
     //getters for keyName and value 
     //hashcode and equals to be put as a key of a map
}

Реализация метода поиска будет

public Book lookupBookByISBN(String isbn) {
    Key key = new Key("ISBN",isbn);
    return ((Book)map.get(key));
}

public List<Book> lookupBookByAuthor(String isbn) {
        Key key = new Key("Author",isbn);
        return (List<Book>map.get(key));
    }

Вставка в карту должна выполняться аккуратно, поскольку один и тот же объект необходимо дважды вставить в карту.

public void putBook(Book book) {
   Key key = new Key("ISBN",book.getISBN());
   map.put(key,book);
   key = new Key("Author",book.getAuthor());
   List<Book> list = map.get(key);
   if (null == list) {
      list = new ArrayList<Book>();
      map.put(key,book);
   }
   list.add(book);

}

Мне почему-то кажется, что это не очень хорошая идея, и мне может понадобиться поместить один и тот же объект на карту N раз, в зависимости от N измерений, по которым мне нужно искать объект.

Есть ли другой способ сделать то же самое лучше?

1 Ответ

4 голосов
/ 22 февраля 2011

Когда вы сохраняете объект в коллекции (любого типа), вы сохраняете только ссылку на объект. Итак, используйте несколько карт, у вас будет только одна копия реального объекта.

Например

Map<String,MyBigObject> map1 = new HashMap...
Map<String,MyBigObject> map2 = new HashMap...
MyBigObject mbo = new MyBigObject(...);
map1.put(mbo.getISBN(),mbo);
map2.put(mbo.getAuthor(),mbo);

Единственный объект mbo теперь доступен через любую карту.

РЕДАКТИРОВАТЬ: Если вы беспокоитесь о сложности нескольких карт, усложняющих код, напишите класс MultiMap, который содержит все карты и управляет ими любым удобным для вас способом. У вас могут быть методы add(MyBigObject...), которые вставляют объект во все карты, используя различные методы доступа к свойствам для установки правильного ключа, а затем методы поиска, такие как getByAuthor(...) и getByISBN(...), и все, что вам нужно. Скройте всю сложность простого простого взаимодействия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...