I want a limited size map with some duplicated keys. When size is reached I want delete the oldest entry.
for example, this data set:
MAX_SIZE=5;
map.put(100,"OLDEST");
map.put(101,"XXXX");
map.put(101,"YYYY");
map.put(102,"ZZZZ");
map.put(103,"GGGG");
Then I want to insert a new entry in the map
myLength = map.size()
if(myLength>=MAX_SIZE){
map.remove(the OLDEST)
}
map.put(105,"NEW")
I was thinking in guava multimap, but how delete the oldest entry in multimap?
They KEY is a Long, maybe I need do a for? (not efficient)
oldest=MAX_LONG
for(Long key:map){
if(key<oldest){
oldest=key
}
}
map.remove(oldest)
Use a LinkedListMultimap: it preserves the insertion order, so removing the oldest entry is just a matter of removing the first element of the list returned by entries()
Related
Is there a way to efficiently remove entries from a HashMap which values are in a specified range.
I have following HashMap
private Map<String, Long> accessTimes = new HashMap<>();
I would like to remove all entries where values are between 0 and 200.
Is it possible without iterating through them HashMap? Thank you for any tips.
No you can't do that without iterating over all keys in the map.
In a HashMap, entries are stored in buckets based on the hash code of the entry's key. Therefore, entries are not sorted which forces you to visit all elements to determine if one needs to be removed.
CODE IS HERE is a nice and simple example of TreeMap in java to keep track of the key-value pairs added to the map in a sorted order. However, I am unsure on how to ensure that I only keep 10 items in the TreeMap. How to ensure that the size of the TreeMap is always a constant, like 10? So the original problem is: to keep track of the top ten key-value pairs weighted by value in the TreeMap while the stream of key-value keeps coming in.
I want to see how the to write the code in java to constrict the size of the TreeMap. I'm thinking it is something like this:
first add the new key-value pair into the TreeMap, then you check the size of the TreeMap, if it is greater than 10, then delete the smallest key-value pair from the TreeMap and the size returns back to 10 and the TreeMap is ready to add a new key-value pair inside of it.
I have a Map of Long and String - Map which stores my timestamp as the key and value as my data.
Map<Long, String> eventTimestampHolder = new HashMap<Long, String>();
Now I want to get 100 most recent data from the above map by looking at timestamp which is part of key and then keep on adding those data in a List of String. In general populate the 100 most recent data in a List.
What is the best way to do this? Can I use TreeMap here and it will sort my keys basis on the timestamp properly?
In general my timestamp is going to look like this - 1417686422238 and it will be in milliseconds
In case you mean by "recent" recently added, then you can try LinkedHashMap which will maintain the order of insertion. Then you can iterate over the first 100 items.
You can iterate over the map like this:
for(Long key : eventTimestampHolder.keySet()) {
String value = eventTimestampHolder.get(key);
}
For any key that can be sorted, you should use a SortedMap (unless there are other requirements making it unsuitable). A TreeMap is a sorted map. Since you need the most recent k entries, you need the largest keys first. This can be done by going through the k first keys in the map's descendingKeySet as follows, a one-liner in Java-8:
eventTimestampHolder.descendingKeySet().stream().limit(k); // in your case, k = 100
If you want not just the keys, but the values as well, then you could find the k'th key, and then use
// the 2nd arg is a boolean indicating whether the k'th entry will be included or not
eventTimestampHolder.tailMap(kthTimestamp, true);
One thing to remember when using tailMap is that it will be backed by the original eventTimestampHolder map, and any changes to that will be reflected in the returned tail map.
What's the fastest way how to iterate over linked hash map, I need 100 last keys and first 20 keys. The size of this map will be in most cases over 500-1500, thanks
LinkedHashMap<Integer, Float> doc_1 = service5.getMatchingValue(query);
If you iterate over a HashMap you still would have O(n) runtime, as you would iterating over any other datastructure...
Iterating over a HashMap is just as time consuming as iterating over any DS.
If you only need specific entries of a hashmap, you might want to keep information on the required keys and only loop over those keys. Access to an element in a HashMap using its key is O(1) (or atleast amorized), accessing M entries (by their keys) using direct access results thus in O(M) runtime with O(M) << O(N).
You could perhaps keep the last 100 keys in a cache and just loop over (a copy) of the cache to have the best possible access (in terms of performance) in combination with your HashMap.
I'm trying to process a large amount of data and I'm a bit stuck on the best way to process the final calculation.
I have a HashMap. Each Book object has a data value called COUNT that holds how many times that book appears in my particular context. I want to iterate through the entire HashMap and do record the top ten most-appearing books in an array. At the same time, I also want to remove those top ten books from the HashMap. What is the best way to do this?
Yes, you can't remove using a for loop because like this
for(Book curBook: yourMap.values())
You will get a ConcurrentModificationException. To remove elements while iterating, you have to use an iterator, for example:
HashMap<Book> yourMap;
Collection<Book> entries = yourMap.values();
Iterator<Book> iterator = entries.iterator();
while(iterator.hasNext()) {
Book curBook = iterator.next();
if (yourConditionToRemove) {
iterator.remove();
}
}
If this is a frequent operation, consider using TreeMap as suggested by Bohemian or at least keep a separate Map with most read Books.
I would copy the map into a SortedMap, such as TreeMap, using a comparator that compares the count.
The rest should be obvious.
There is a tournament algorithm that runs in O(n) time and can be useful for large data ,
Optimal algorithm for returning top k values from an array of length N
If the data is not very huge then I would recommend using Collections.sort and creating a subList from your Map.
Another option is it to keep them in TreeMap and implement Comparable in your Book Object , that way your Map is always sorted . This is particularly useful if you are doing additions to your Map as you don't want to sort them every time you change an object.
I am not that proficient at Java, but I can think about the following algorithm. Assuming that the HashMap stores books according to their unique identifier (i.e. it gives you no ordering hints about COUNT). You can:
Define a sequence with capacity for ten books in which they will be stored ordered by COUNT. For clarity, I will call this sequence O10S (Ordered 10-element sequence)
Traverse your hashmap. For each element e in HashMap:
If O10S is not full yet insert e in O10S
Otherwise, if e has a COUNT higher than the element o in O10S with the minimum COUNT (which should be easily identifiable since O10S is ordered): remove o from O10S, insert e in O10S
For every o in O10S, remove o from HashMap
The algorithm is linear with respect of the elements in HashMap (you only need to traverse the HashMap once)