HashMap - 获取第一个键值

222

以下是HashMap中包含的值

statusName {Active=33, Renewals Completed=3, Application=15}

获取第一个键(即Active)的Java代码

Object myKey = statusName.keySet().toArray()[0];

我们如何收集第一个键“Value”(即33),我想将“Key”和“Value”分别存储在不同的变量中。


13
你知道HashMap的条目是无序的,所以“第一个”在修改地图时会发生变化吗? - NPE
2
你明白在 HashMap 中没有特定的顺序吗?如果你对它进行任何修改,你可能会得到完全不同的结果。 - Jon Skeet
1
不,运行顺序不能保证每次都相同,但在同一线程中,可以依赖于顺序。 - hd1
4
@JonSkeet 其实这是一个非常有价值的问题。在 Groovy 中,有很多情况下你会得到一个看起来像是一组由单个键值对组成的映射列表的结构。迄今为止,我还没有找到一种简单/明显(Groovy)的方法来打印出所有的值。如果键是恒定的,那么只需使用 collection.each{println it.key} 来打印出每个值就可以了,但是如果键不是恒定的,则不太明显,但是 collection.each{println it.values()[0]} 可以工作(这是这里一些答案的改进...)。 - Bill K
@BillK:如果你知道每个映射都只有一个条目,那么这实际上是一个不同的问题,而且更有意义。 - Jon Skeet
11个回答

392

你可以尝试这样做:

 Map<String,String> map = new HashMap<>();
 Map.Entry<String,String> entry = map.entrySet().iterator().next();
 String key = entry.getKey();
 String value = entry.getValue();

请记住,HashMap 不保证插入顺序。使用 LinkedHashMap 来保持顺序不变。

例如:

 Map<String,String> map = new LinkedHashMap<>();
 map.put("Active","33");
 map.put("Renewals Completed","3");
 map.put("Application","15");
 Map.Entry<String,String> entry = map.entrySet().iterator().next();
 String key= entry.getKey();
 String value=entry.getValue();
 System.out.println(key);
 System.out.println(value);

输出:

 Active
 33

更新:Java 8 或更高版本中获取第一个键。

Optional<String> firstKey = map.keySet().stream().findFirst();
if (firstKey.isPresent()) {
    String key = firstKey.get();
}

首先非常感谢您的回答!我没有想到会得到回复... 其次,我发现在运行时无法保存泛型存在问题。最终,我通过使用 Gson 将值对象转换为 String,然后将其解析回我的类类型来解决了这个问题。虽然有些丑陋,但我真的找不到其他解决方案,而在其他语言中这样做是如此容易(我正在学习 Java)。 - Blue Bot
@darthydarth,你可以给我发送电子邮件。ruchiragayan@gmail.com - Ruchira Gayan Ranaweera
@SimonBaars 不,HashMap 的设计并不是线程安全的。但是你可以根据你对 HashMap 的使用来使它线程安全。你可以直接使用 HashTable,但是你应该记住它也存在比 HashMap 更多的性能问题。 - Ruchira Gayan Ranaweera
@RuchiraGayanRanaweera 当使用java.util.Hashtable尝试检索第一个元素时,代码会是什么?而且,map.keySet().toArray()[0]不是线程安全的吗? - Simon Baars
快速问题:map.entrySet().iterator().next() 是 o(1) 运行时间还是 o(n) 运行时间。感谢任何人能够回答... - Fiddle Freak
显示剩余4条评论

100

获取“第一个”值:

map.values().toArray()[0]

要获取"first"键的值:

map.get(map.keySet().toArray()[0])
注意:上述代码已经经过测试并且可用。
我说“第一”,因为HashMap的条目是无序的。
但是,LinkedHashMap按照插入顺序迭代其条目 - 如果插入顺序很重要,您可以使用它来实现您的映射。

1
你首先需要检查地图不为空。 - ACV

61

Java 8的做法是:

String firstKey = map.keySet().stream().findFirst().get();


3
如果我们有这个键,可以使用map.get(firstKey)来检索第一个值。只是一个提示。 :) - Upen
2
不要使用这种方法!如果“map”变量是HashMap类型,这种方法将无法可靠地工作,请转换为Array或LinkedHashMap! - Tobias Kaufmann

12

为了获取完整的第一条目录,您也可以尝试以下方法:

Map.Entry<String, String> entry = map.entrySet().stream().findFirst().get();
String key = entry.getKey();
String value = entry.getValue();
以下展示如何获取第一个条目的键:

String key = map.entrySet().stream().map(Map.Entry::getKey).findFirst().get();
// or better
String key = map.keySet().stream().findFirst().get();
以下是如何获取第一个条目的值的示例:
String value = map.entrySet().stream().map(Map.Entry::getValue).findFirst().get();
// or better
String value = map.values().stream().findFirst().get();

此外,如果您想获取地图中第二个(或第三个等)项目,并且已经验证该地图至少包含2个条目,则可以使用以下方法。

Map.Entry<String, String> entry = map.entrySet().stream().skip(1).findFirst().get();
String key = map.keySet().stream().skip(1).findFirst().get();
String value = map.values().stream().skip(1).findFirst().get();

我注意到如果你知道map只包含一个值,那么迭代器 keys.values().iterator().next();keys.values().stream().findFirst().get(); 要快得多。如果你知道该函数将经常被调用,并且大多数情况下map只会保存一个值,这可能是一种性能优化。 - BarbetNL

8

Kotlin答案

获取第一个键然后获取键的值。Kotlin中有"first()"函数:

val list = HashMap<String, String>() // Dummy HashMap.

val keyFirstElement = list.keys.first() // Get key.

val valueOfElement = list.getValue(keyFirstElement) // Get Value.

我不知道,但是对于我来说,它返回的是最后一个值而不是第一个值,我不知道为什么。 - Ahmed Elsayed
你是否会更改或更新你的列表?也许你使用"list.keys.first()"获取键,然后尝试获取值,但是你的列表已经发生了变化。 - canerkaseler

4
我们如何收集第一个键"Value"(即33)?
通过使用youMap.get(keyYouHave),您可以获取它的值。
想要将“Key”和“Value”存储在单独的变量中?
是的,您可以将其分配给变量。
等等..........还没结束。
如果您(业务逻辑)依赖插入和检索的顺序,您将看到奇怪的结果。Map不是有序的,它们不会按顺序存储。请注意这个事实。使用一些替代方案来保留您的顺序。可能是LinkedHashMap

4
请注意,您的逻辑流程绝不能依赖于按某个顺序访问 HashMap 元素,简单来说,因为 HashMap 不是有序 Collection,也不是它们的目标。 (您可以在此文章中了解有序和排序集合的更多信息。)
回到文章本身,通过加载第一个元素的键,您已经完成了一半的工作。
Object myKey = statusName.keySet().toArray()[0];

只需调用map.get(key)以获取相应的值:
Object myValue = statusName.get(myKey);

1
请记住,一般情况下,地图中的插入顺序不被尊重。试试这个:
    /**
     * Get the first element of a map. A map doesn't guarantee the insertion order
     * @param map
     * @param <E>
     * @param <K>
     * @return
     */
    public static <E,K> K getFirstKeyValue(Map<E,K> map){
        K value = null;
        if(map != null && map.size() > 0){
            Map.Entry<E,K> entry =  map.entrySet().iterator().next();
            if(entry != null)
                value = entry.getValue();
        }
        return  value;
    }

我仅在确信 map.size() == 1 时使用此操作。


1
改进whoami的答案。由于findFirst()返回一个Optional,因此最好检查是否有值。
 var optional = pair.keySet().stream().findFirst();

 if (!optional.isPresent()) {
    return;
 }

 var key = optional.get();

此外,一些人评论说查找 HashSet 的第一个键是不可靠的。但有时我们有 HashMap 对;即在每个映射中,我们有一个键和一个值。在这种情况下,快速查找此类对的第一个键是方便的。


0

这也是一种不错的方法 :)

Map<Integer,JsonObject> requestOutput = getRequestOutput(client,post);
int statusCode = requestOutput.keySet().stream().findFirst().orElseThrow(() -> new RuntimeException("Empty"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接