Java 如何在不迭代的情况下从哈希图中获取一个条目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1509391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:37:34  来源:igfitidea点击:

how to get the one entry from hashmap without iterating

javacollections

提问by nilesh

Is there a elegant way of obtaining only one Entry<K,V>from HashMap, without iterating, if key is not known.

Entry<K,V>如果键未知,是否有一种优雅的方法可以从 HashMap 中只获取一个,而不进行迭代。

As order of entry of entry is not important, can we say something like

由于进入的顺序并不重要,我们可以这样说吗

hashMapObject.get(zeroth_index);

Although I am aware that there exist no such get by index method.

虽然我知道不存在这样的 get by index 方法。

If I tried approach mentioned below, it would still have to get all the entry set of the hashmap.

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

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

Suggestions are welcome.

欢迎提出建议。

EDIT: Please suggest any other Data Structure to suffice requirement.

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

采纳答案by Per ?stlund

The answer by Jesper is good. An other solution is to use TreeMap (you asked for other data structures).

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

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

TreeMap has an overhead so HashMap is faster, but just as an example of an alternative solution.

TreeMap 有开销,因此 HashMap 更快,但仅作为替代解决方案的示例。

回答by Jesper

Maps are not ordered, so there is no such thing as 'the first entry', and that's also why there is no get-by-index method on Map(or HashMap).

地图是没有顺序的,所以没有“第一个条目”这样的东西,这也是为什么在Map(or HashMap)上没有 get-by-index 方法的原因。

You could do this:

你可以这样做:

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

(Note: Checking for an empty map omitted).

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

Your code doesn't get all the entries in the map, it returns immediately (and breaks out of the loop) with the first entry that's found.

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

To print the key and value of this first element:

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

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

Note: Calling iterator()does not mean that you are iterating over the whole map.

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

回答by cadrian

I guess the iterator may be the simplest solution.

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

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

Another solution (not pretty):

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

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

Or yet (not better):

或者(不是更好):

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

回答by janko

What do you mean with "without iterating"?

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

You can use map.entrySet().iterator().next()and you wouldn't iterate through map (in the meaning of "touching each object"). You can't get hold of an Entry<K, V>without using an iterator though. The Javadoc of Map.Entrysays:

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

The Map.entrySet method returns a collection-view of the map, whose elements are of this class. The only way to obtain a reference to a map entry is from the iterator of this collection-view. These Map.Entry objects are valid only for the duration of the iteration.

Map.entrySet 方法返回地图的集合视图,其元素属于此类。获取映射条目引用的唯一方法是从此集合视图的迭代器中获取。这些 Map.Entry 对象仅在迭代期间有效。

Can you explain in more detail, what you are trying to accomplish? If you want to handle objects first, that match a specific criterion (like "have a particular key") and fall back to the remaining objects otherwise, then look at a PriorityQueue. It will order your objects based on natural order or a custom-defined Comparatorthat you provide.

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

回答by Joachim Sauer

Why do you want to avoid calling entrySet()it does notgenerally create an entirely new object with its own context, but instead just provide a facade object. Simply speaking entrySet()is a pretty cheap operation.

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

回答by KLE

Following your EDIT, here's my suggestion :

根据您的编辑,这是我的建议:

If you have only one entry, you might replace the Map by a dual object. Depending on the types, and your preferences:

如果您只有一个条目,您可以用双对象替换 Map。根据类型和您的偏好:

  • an array (of 2 values, key and value)
  • a simple object with two properties
  • 一个数组(2 个值,键和值)
  • 具有两个属性的简单对象

回答by Michael Easter

This would get a single entry from the map, which about as close as one can get, given 'first' doesn't really apply.

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

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

回答by Adriaan Koster

If you really want the API you suggested, you could subclass HashMap and keep track of the keys in a List for example. Don't see the point in this really, but it gives you what you want. If you explain the intended use case, maybe we can come up with a better solution.

如果你真的想要你建议的 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);
    }
}

EDIT: I deliberately did not delve into the generics side of this...

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

回答by Wiktor Misiek

Get values, convert it to an array, get array's first element:

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

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

W.

W.

回答by dmgcodevil

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

This approach doesn't work because you used HashMap. I assume using LinkedHashMap will be right solution in this case.

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