如何从hashmap中获取一个条目而不进行迭代

nil*_*esh 164 java collections

Entry<K,V>如果密钥未知,是否有一种优雅的方式只从HashMap 中获取一个,而不进行迭代.

由于进入的顺序并不重要,我们可以说类似的东西

hashMapObject.get(zeroth_index);
Run Code Online (Sandbox Code Playgroud)

虽然我知道没有这样的get by index方法.

如果我尝试下面提到的方法,它仍然必须得到hashmap的所有条目集.

for(Map.Entry<String, String> entry : MapObj.entrySet()) {
    return entry;
}
Run Code Online (Sandbox Code Playgroud)

欢迎提出建议.

编辑:请建议任何其他数据结构满足要求.

Jes*_*per 247

地图不是有序的,因此没有"第一个条目"这样的东西,这也是为什么在Map(或HashMap)上没有get-by-index方法的原因.

你可以这样做:

Map<String, String> map = ...;  // wherever you get this from

// Get the first entry that the iterator returns
Map.Entry<String, String> entry = map.entrySet().iterator().next();
Run Code Online (Sandbox Code Playgroud)

(注意:省略了检查空地图).

您的代码不会获取地图中的所有条目,它会立即返回(并且会突破循环)并找到第一个条目.

要打印第一个元素的键和值:

System.out.println("Key: "+entry.getKey()+", Value: "+entry.getValue());
Run Code Online (Sandbox Code Playgroud)

注意:调用iterator()并不意味着您在整个地图上进行迭代.

  • 只是旁注:`LinkedHashMap`按照插入顺序保存键. (3认同)
  • 是的,一般的地图不是有序的,但是一些`Map`实现,比如`LinkedHashMap`和`TreeMap`确实有一个定义的顺序.(`HashMap`没有). (2认同)

小智 91

Jesper的答案很好.另一种解决方案是使用TreeMap(您要求其他数据结构).

TreeMap<String, String> myMap = new TreeMap<String, String>();
String first = myMap.firstEntry().getValue();
String firstOther = myMap.get(myMap.firstKey());
Run Code Online (Sandbox Code Playgroud)

TreeMap有一个开销,所以HashMap更快,但只是作为替代解决方案的一个例子.


cad*_*ian 28

我想迭代器可能是最简单的解决方案.

return hashMapObject.entrySet().iterator().next();
Run Code Online (Sandbox Code Playgroud)

另一个解决方案(不太漂亮):

return new ArrayList(hashMapObject.entrySet()).get(0);
Run Code Online (Sandbox Code Playgroud)

或者(不是更好):

return hashMapObject.entrySet().toArray()[0];
Run Code Online (Sandbox Code Playgroud)

  • 没有理由使用第二个或第三个版本.第一个完全没问题,另外两个通过提供数组/列表而浪费了大量时间. (7认同)
  • 我同意,因此"不漂亮"的评论;-) (4认同)

小智 13

获取值,将其转换为数组,获取数组的第一个元素:

map.values().toArray()[0]
Run Code Online (Sandbox Code Playgroud)

W.


Joa*_*uer 8

为什么要避免调用entrySet()它通常不会创建具有自己的上下文的全新对象,而只是提供一个外观对象.简单来说entrySet()就是一个相当便宜的操作.


Cac*_*nta 7

如果您使用的是Java 8,它就像findFirst()一样简单:

快速举例:

Optional<Car> theCarFoundOpt = carMap.values().stream().findFirst();

if(theCarFoundOpt.isPresent()) {
    return theCarFoundOpt.get().startEngine();
}
Run Code Online (Sandbox Code Playgroud)


Adr*_*ter 6

如果你真的想要你建议的API,你可以继承HashMap并跟踪List中的键,例如.真的没有看到这一点,但它给你你想要的.如果您解释预期的用例,也许我们可以提出更好的解决方案.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
public class IndexedMap extends HashMap {

    private List<Object> keyIndex;

    public IndexedMap() {
        keyIndex = new ArrayList<Object>();
    }

    /**
     * Returns the key at the specified position in this Map's keyIndex.
     * 
     * @param index
     *            index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException
     *             if the index is out of range (index < 0 || index >= size())
     */
    public Object get(int index) {
        return keyIndex.get(index);
    }

    @Override
    public Object put(Object key, Object value) {

        addKeyToIndex(key);
        return super.put(key, value);
    }

    @Override
    public void putAll(Map source) {

        for (Object key : source.keySet()) {
            addKeyToIndex(key);
        }
        super.putAll(source);
    }

    private void addKeyToIndex(Object key) {

        if (!keyIndex.contains(key)) {
            keyIndex.add(key);
        }
    }

    @Override
    public Object remove(Object key) {

        keyIndex.remove(key);
        return super.remove(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我故意没有深入研究这个泛型方面......