Java cache design question
I need to develop a simple cache (no concurrency or refresh required) to hold different types of objects. The lookup of these objects may be in a different way. Like lets say we are caching book object which has ISBN number and author. Lookup of this object can be either by ISBN number like
Book lookupBookByISBN(String isbn);
OR it could be a lookupByAuthor like
List lookupBookByAuthor(String authorName);
In a very simple way, it means I can have a Cache object which has two maps one to store book object by ISBN and another to store the same object by authorname.
Like this, think of many such object type like book, so I do not want to store the same object in different maps just because the lookup of them are different.
One way I was thinking of having a single Map whose key is a custom Key object and value is Object (so that I can store any object or list of object) The Key object is a immutable object which might开发者_运维问答 look like this
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
}
Implementation of lookup method will be
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));
}
The insert into map needs to be carefully done as the same object needs to be inserted twice into the map.
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);
}
I somehow feel this might not be a good idea and I might need to put the same object in the map N number of times depending upon N dimensions by which I need to lookup the object.
Is there anyother way to design the same in a better way?
When you store an object in a collection (of any kind), you only store a reference to the object. So go ahead and use multiple maps, you will have only one copy of the actual object.
For example
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);
The single object mbo
is now accessible via either map.
EDIT: If you're worried about the complexity of multiple maps complicating the code, write a class MultiMap
that contains all the maps and manages them in whatever way you want. You could have methods add(MyBigObject...)
which inserts the object into all the maps using the various property accessors to set the correct key, and then lookup methods such as getByAuthor(...)
and getByISBN(...)
, and whatever else you need. Hide all the complexity behind a simple unified interace.
精彩评论