'Delete top or bottom n elements of a map

I have a HashMap like below:

map.put("1","One");    \\KV1
map.put("3","Three");  \\KV2
map.put("2","Two");    \\KV3
map.put("5","Five");   \\KV4
map.put("4","Four");   \\KV5

Is there any function where I can get top 3(KV1,KV2,KV3) or bottom 3(KV3,KV4,KV5) key-value pairs? or may be any function by which I can delete top n or bottom n elements?

Thanks in advance.



Solution 1:[1]

You can remove n elements from a map without iteration this way

map.keySet().removeAll(Arrays.asList(map.keySet().toArray()).subList(0, 5));

Solution 2:[2]

There are some terrible answers to this question.

Firstly, it depends what you mean by top. Insertion order or natural sorted order?

A LinkedHashMap preserves insertion order. A TreeMap maintains its keys in natural sorted order.

If it's a sorted map, then you can request a view of the keys using Treemap.headMap(K key), tailMap() and subMap();

If it's insertion order then you'll have to extract the submap yourself. Guava provides a helper in Maps called Maps.filterKeys that will allow you to view the underlying map fltered by a Predicate you pass in. This is useful if you don't want to copy the map, just view it differently. Of course, you can always copy the resultant map if that's what you want or roll your own more specialised case.

This question shows how to write a generic subMap method for LinkedHashMaps.

Solution 3:[3]

LinkedHashMap maintains a linked list of the entries in the map, in the order in which they were inserted.

    Map<String,String> map = new LinkedHashMap<String, String>();
    map.put("1","One");    //KV1
    map.put("3","Three");  //KV2
    map.put("2","Two");    //KV3
    map.put("5","Five");   //KV4
    map.put("4","Four");   //KV5

    for(Map.Entry<String, String> mapentry : map.entrySet() ){
        System.out.println(mapentry.getKey()); // you can get the keys and values 
        System.out.println(mapentry.getValue());
    }

Solution 4:[4]

Maybe this can work for skipping n elements at the end of list, limit here is (n-m) where m is the number of elements to be skipped at the bottom of the list

items.entrySet().stream()
          .limit(limit)
          .collect(LinkedHashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), Map::putAll );

Or you can use skip to ignore elements at the start of the map, where skipElements here is the number of elements that you want to skip in the beginning of the list,

items.entrySet().stream()
              .skip(skipElements)
              .collect(LinkedHashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), Map::putAll );

I haven't tested this.

Solution 5:[5]

Use a SortedMap, such as a TreeMap instead of a HashMap. You can then iterate through the keys in order. That makes it possible to find and delete the 3 smallest keys. Delete the three largest key by finding and then deleting the last key three times.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Community
Solution 3
Solution 4
Solution 5