我需要开发一个简单的缓存(不需要并发或刷新)来保存不同类型的对象。查找这些对象的方式可能不同。就像我们说的那样,我们正在缓存具有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维。
还有其他方法可以更好地设计相同的方法吗?
答案 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背后的所有复杂性。