How to get nth item from a TreeMap?

5.5k Views Asked by At

I have a TreeMap<Date, Integer> and I want to fetch the nth item from that map. What I came up with now is this:

((Integer)myTreeMap.values().toArray()[index]).intValue();

but this feels quite clunky, not to mention what is happening on the heap or with performance?

Is there a concise way to get the nth item from a TreeMap/SortedMap ?

4

There are 4 best solutions below

4
LppEdd On BEST ANSWER

Edit: an alternative is

final Optional<T> first =
        treeMap.values()
               .stream()
               .skip(index - 1)
               .findFirst();

if (first.isPresent()) {
    final T value = first.get();
}

What about

final List<T> values = new ArrayList<>(myTreeMap.values());
final T value = values.get(index);

T is just a generic type in place of your Map value type.
index is your nth element.

As pointed out, that's inefficient for large maps, as internally the ArrayList constructor the toArray method is called

public Object[] toArray() {
    // Estimate size of array; be prepared to see more or fewer elements
    Object[] r = new Object[size()];
    Iterator<E> it = iterator();
    for (int i = 0; i < r.length; i++) {
        if (! it.hasNext()) // fewer elements than expected
            return Arrays.copyOf(r, i);
        r[i] = it.next();
    }
    return it.hasNext() ? finishToArray(r, it) : r;
}
4
Tim Biegeleisen On

We can try using a stream here. In the snippet below, we create a sorted map with five entries. Then, we create a stream, skipping the first 3 elements, and using findFirst to capture the first element.

Map<Integer, String> myTreeMap = new TreeMap<>();
myTreeMap.put(1, "one");
myTreeMap.put(2, "two");
myTreeMap.put(3, "three");
myTreeMap.put(4, "four");
myTreeMap.put(5, "five");
String fourth = myTreeMap.entrySet().stream()
   .skip(3)
   .map(map -> map.getValue()).findFirst().get();
System.out.println("fourth value in map is: " + fourth);
0
krishna Prasad On

You can use steam and skip n-1 elements and take the first as below: tmap.entrySet().stream().skip(n-1).findFirst();. Details with data set examples:

TreeMap<Date, Integer> tmap = new TreeMap<Date, Integer>();
tmap.put(new Date(2014, 1, 1), 0);
tmap.put(new Date(2015, 1, 1), 1);
tmap.put(new Date(2016, 1, 1), 2);
tmap.put(new Date(2017, 1, 1), 3);
tmap.put(new Date(2018, 1,1 ), 4);

System.out.println(tmap);

// Let's find the nth elements i.e n = 3;
int n = 3;
System.out.println(" " + n + " elements: ");
System.out.println(tmap.entrySet().stream().skip(n-1).findFirst());

Output as follow:

{Sun Feb 01 00:00:00 IST 3914=0, Mon Feb 01 00:00:00 IST 3915=1, Tue Feb 01 00:00:00 IST 3916=2, Thu Feb 01 00:00:00 IST 3917=3, Fri Feb 01 00:00:00 IST 3918=4}
3 elements: 
Optional[Tue Feb 01 00:00:00 IST 3916=2]
0
3rdRockSoftware On

I have found a way of getting the Nth key / value from a Map. and that is simply to add a counter.

int count = 1;
for (Map.Entry entry : Map.entrySet())
        {
            if (count == 1) //the Nth value
            {
                System.out.println(count + " "
                     + entry.getKey() + " "
                     + entry.getValue());
            }
            count++;
        }