【发布时间】:2011-02-23 01:11:55
【问题描述】:
我需要开发一个简单的缓存(不需要并发或刷新)来保存不同类型的对象。这些对象的查找可能采用不同的方式。就像假设我们正在缓存具有 ISBN 号和作者的书籍对象。此对象的查找可以通过 ISBN 编号,如
图书查找BookByISBN(String isbn);
或者它可能是一个lookupByAuthor,比如
List lookupBookByAuthor(String authorName);
以一种非常简单的方式,这意味着我可以拥有一个 Cache 对象,该对象有两个映射,一个用于按 ISBN 存储图书对象,另一个用于按作者姓名存储相同的对象。
像这样,想想很多像书这样的对象类型,所以我不想因为它们的查找不同而将同一个对象存储在不同的地图中。
我正在考虑使用单个 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 个维度。
还有其他更好的方式来设计相同的吗?
【问题讨论】:
-
我建议为不同的查找类型使用不同的地图。这样您就不需要复合键并且可以使用
Map<String, Book> isbnMap和MultiMap<String, Book> authorMapMultiMap 对于一对多关系很有用。您的每个查找都只是这些地图上的get(name)。