I have a program, that has a ConcurrentHashMap
where different Threads can add/remove items from the map.
I'm interested to know what's the best approach to read the map in chunks of 25 items. What I want to do is something like this: user clicks on a button and reads 25 items from the map( doesn't matter the order). After that he can click a "Next" button and read another 25 items( that are different from the first 25 ), and so on.
I'm not sure if I can do this with a ConcurrentHashMap
. I don't want to use a database , and I want to keep this in memory.
I don't think converting the Map
into an ArrayList
will help, because items are added/ removed from the map, most of the time.
I'm open to any solution, even a 3rd party library.
UPDATE: I'm also not tied to ConcurrentHashMap
. I'm just looking for the best solution
UPDATE 2: They keys are String
Thanks
In your case, since String keys are strictly ordered, ConcurrentSkipListMap
is a way to go.
get
/ put
/ remove
are as fast as O(log N)
.To get the next page from ConcurrentSkipListMap, call tailMap
with the last key of the previous page as an anchor and then construct an iterator or a stream from the result submap:
return map.tailMap(lastKey, false).entrySet()
.stream()
.limit(pageSize)
.collect(Collectors.toList());
Note that tailMap
will succeed even if the anchor key is removed from the map. The iteration will proceed from the next key larger than the anchor.
If keys are not strictly ordered, or if O(1) complexity is required, then you may prefer an alternative suggestion - an open-addressed hash table traversed in the order of cell indices. However there is no such implementation among standard Java classes. The thread-safety of such maps is typically achieved by locking.