I'd like to use a map that would be equivalent to ConcurrentMap
(I want the equivalent of the putIfAbsent method) but that would not force me to create the object beforehand.
For example when I do this:
m.putIfAbsent( key, new CyclingArray() );
I may end up creating a new CyclingArray (whatever that is) object for nothing.
Of course I realize I could lock up the entire map but that would be defeating the whole point of a ConcurrentMap
.
Could something like the following work conceptually?
m.putIfAbsent( key, new Callback<CyclingArray>() {
@Override
public CyclingArray provide() {
return new CyclingArray(); // only called if the key wasn't already present
}
}
Do you know of any library offering a map that:
putIfAbsent
method.ConcurrentHashMap
implementation does, for example)Note that I'm not asking if the above example can be done with a ConcurrentMap
(it cannot AFAIK).
I was thinking about extending ConcurrentHashMap
and overloading putIfAbsent with the callback version but sadly ConcurrentHashMap
internally uses a final Segment class.
Before re-inventing the wheel I'd like to know if there are any maps out there already offering a similar functionality.
This is a common use case you are looking for, its called memoization. I would look at MapMaker
You would be able to create a computingMap and put your creating function there:
ConcurrentMap<Key, CyclingArray> graphs = new MapMaker()
.concurrencyLevel(32)
.makeComputingMap(
new Function<Key, CyclingArray>() {
public CyclingArray apply(Key key) {
return new CyclingArray(); // only called if the key wasn't already
}
});
Here the Function
will only be called if the Key
is not present
And I do know future plans in Java have a computingMap type interface will come with standard Java, unfortunately at this point you will have to delegate to google-collections.