Java缓存设计问题

时间:2011-02-22 16:54:40

标签: java caching

我需要开发一个简单的缓存(不需要并发或刷新)来保存不同类型的对象。查找这些对象的方式可能不同。就像我们说的那样,我们正在缓存具有ISBN号和作者的书籍对象。查找此对象可以是ISBN编号,如

  

Book lookupBookByISBN(String isbn);

或者它可以是像

这样的lookupByAuthor
  

列出lookupBookByAuthor(String authorName);

以一种非常简单的方式,这意味着我可以拥有一个Cache对象,它有两个映射,一个用于按ISBN存储book对象,另一个用于通过authorname存储同一个对象。

像这样,想到很多像book这样的对象类型,所以我不想将相同的对象存储在不同的地图中,因为它们的查找是不同的。

我想到的一种方法是使用单个Map,其键是自定义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 个答案:

答案 0 :(得分:4)

将对象存储在集合(任何类型)中时,只将引用存储到对象中。因此,继续使用多个地图,您将只有一个实际对象的副本。

例如

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(...)等方法,以及其他任何方法需要。隐藏简单统一的interace背后的所有复杂性。