如何从 TreeMap 中获取第 n 个项目?

How to get nth item from a TreeMap?

我有一个 TreeMap<Date, Integer>,我想从该地图中获取第 n 个项目。我现在想到的是:

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

但这感觉很笨拙,更不用说堆上或性能上发生了什么?

有没有一种简洁的方法可以从 TreeMap/SortedMap 中获取第 n 项?

我们可以在这里尝试使用流。在下面的代码片段中,我们创建了一个包含五个条目的排序映射。然后,我们创建一个流,跳过前 3 个元素,并使用 findFirst 捕获第一个元素。

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);

编辑:另一种选择是

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

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

怎么样

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

T 只是一个通用类型,代替了您的 Map 值类型。
index 是您的 nth 元素。

正如所指出的那样,这对于大型地图来说效率低下,因为在 ArrayList 构造函数内部调用了 toArray 方法

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;
}

你可以使用steam,跳过n-1个元素,取第一个如下: tmap.entrySet().stream().skip(n-1).findFirst();。数据集示例的详细信息:

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());

输出如下:

{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]