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

时间:2009-10-02 13:09:02

标签: java collections

如果密钥未知,是否有一种从HashMap中只获取一个Entry<K,V>的优雅方式,无需迭代。

由于参赛作品的顺序并不重要,我们可以说

hashMapObject.get(zeroth_index);

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

如果我尝试了下面提到的方法,仍然需要获取hashmap的所有条目集

for(Map.Entry<String, String> entry : MapObj.entrySet()) {
    return entry;
}

欢迎提出建议。

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

16 个答案:

答案 0 :(得分:239)

地图不是有序的,因此不存在“第一个条目”,这也是Map(或HashMap)上没有按索引获取方法的原因。< / p>

你可以这样做:

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

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

你的代码没有得到地图中的所有条目,它会立即返回(并且突破循环)并找到第一个条目。

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

System.out.println("Key: "+entry.getKey()+", Value: "+entry.getValue());

注意:调用iterator()并不意味着您正在迭代整个地图。

答案 1 :(得分:89)

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

TreeMap<String, String> myMap = new TreeMap<String, String>();
String first = myMap.firstEntry().getValue();
String firstOther = myMap.get(myMap.firstKey());

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

答案 2 :(得分:28)

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

return hashMapObject.entrySet().iterator().next();

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

return new ArrayList(hashMapObject.entrySet()).get(0);

或者(不是更好):

return hashMapObject.entrySet().toArray()[0];

答案 3 :(得分:13)

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

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

W上。

答案 4 :(得分:8)

为什么你要避免调用entrySet() 它通常用自己的上下文创建一个全新的对象,而只是提供一个Facade对象。简单地说entrySet()是一个非常便宜的操作。

答案 5 :(得分:7)

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

快速举例:

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

if(theCarFoundOpt.isPresent()) {
    return theCarFoundOpt.get().startEngine();
}

答案 6 :(得分: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);
    }
}
编辑:我故意没有深入研究这个泛型方面......

答案 7 :(得分:4)

“没有迭代”是什么意思?

您可以使用map.entrySet().iterator().next()并且不会迭代地图(意思是“触摸每个对象”)。但是,如果不使用迭代器,则无法获得Entry<K, V>Map.Entry的Javadoc说:

  

Map.entrySet方法返回一个   地图的集合视图,其中   元素属于这一类。唯一的   获取地图参考的方法   条目来自于它的迭代器   集合视图。这些Map.Entry   对象仅对   迭代的持续时间。

你能更详细地解释一下,你想要完成什么?如果你想首先处理对象,匹配一个特定的标准(比如“有一个特定的键”),然后再回到其余的对象,那么看一下PriorityQueue。它将根据自然顺序或您提供的自定义Comparator对对象进行排序。

答案 8 :(得分:4)

import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

这种方法不起作用,因为您使用了HashMap。我假设在这种情况下使用LinkedHashMap将是正确的解决方案。

答案 9 :(得分:3)

这将从地图中获得一个条目,该条目尽可能接近,因为“第一个”并不真正适用。

import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

答案 10 :(得分:2)

在这里偶然发现同样的事情...我记得Guava library中的Iterables课程。

获取“第一个”元素:Iterables.getFirst( someMap.values(), null );
基本上与Map.values().iterator().next()相同,但如果地图中没有任何内容,您也可以指定默认值(在本例中为null)。

Iterables.getLast( someMap.values(), null );返回地图中的最后一个元素。

Iterables.get( someMap.values(), 7, null );返回Map中的第7个元素(如果存在),否则返回默认值(在本例中为null)。

请记住,虽然没有订购HashMaps ...所以不要指望Iterables.getFirst返回你在那里扔的第一个项目......同样使用Iterables.getLast或许可以获得 a 映射值。

可能不值得为此添加Guava库,但如果您碰巧使用该库中的其他一些很酷的实用程序......

答案 11 :(得分:1)

在您的编辑之后,这是我的建议:

如果只有一个条目,则可以用双重对象替换Map。 取决于类型和您的偏好:

  • 一个数组(包含2个值,键和值)
  • 具有两个属性的简单对象

答案 12 :(得分:0)

map<string,string>m;
auto it=m.begin();//get iterator to the first element of map(m)
return m->first;//return first string(1st string in map<string,string>m)
//Incase you want the second string 
//you can use return m->second(2st string in map<string,string>m)
//if you want to iterate the whole map you can use loop
for(auto it:m)//m is a map
   cout<<it->first<<endl;

答案 13 :(得分:0)

如果你使用的是 Java 8 或更高版本,你可以使用这个:

return hashMapObject.entrySet().stream().findFirst().orElse(null) // return null if the map is empty

答案 14 :(得分:-1)

为了获取哈希映射的第一个元素,您可以在 kotlin 中使用以下代码:

val data : Float = hashMap?.get(hashMap?.keys?.first())

答案 15 :(得分:-2)

我得到了答案:(这很简单)

获取一个ArrayList,然后投射它并找到arraylist的大小。 这是:

    ArrayList count = new ArrayList();
    count=(ArrayList) maptabcolname.get("k1"); //here "k1" is Key
    System.out.println("number of elements="+count.size());

它会显示尺寸。 (给出建议)。它正在工作。