【问题标题】:how to get the one entry from hashmap without iterating如何在不迭代的情况下从哈希图中获取一个条目
【发布时间】:2010-12-03 07:45:02
【问题描述】:

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

由于输入顺序并不重要,我们可以说类似

hashMapObject.get(zeroth_index);

虽然我知道不存在这种按索引获取的方法。

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

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

欢迎提出建议。

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

【问题讨论】:

    标签: java collections


    【解决方案1】:

    地图没有顺序,因此没有“第一个条目”之类的东西,这也是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();
    

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

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

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

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

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

    【讨论】:

    • 附注:LinkedHashMap 按插入顺序保存键。
    • 是的,地图通常没有顺序,但一些Map 实现,例如LinkedHashMapTreeMap 确实有定义的顺序。 (HashMap 没有)。
    • 比选择的答案更好的答案 - 因为选择的答案使用 TreeMap,它期望键是 Comparable 类型。
    【解决方案2】:

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

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

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

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

    或者还没有(不是更好):

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

    【讨论】:

    • 没有理由使用第二个或第三个版本。第一个很好,另外两个浪费了很多时间,因为什么都提供了一个数组/列表。
    • 我同意,因此“不漂亮”的 cmets ;-)
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        TreeMap 有开销,因此 HashMap 更快,但这只是作为替代解决方案的一个示例。

        【讨论】:

        • 由于某种原因,firstEntry() 方法没有在接口SortedMap 中定义,而只在TreeMapConcurrentSkipListMap 中定义:(
        • firstEntry() 在 NavigableMap 接口中定义。
        • 啊,谢谢,我只看了SortedMap,因为它有firstKey() 方法。
        【解决方案6】:

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

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

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

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

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

              W.

              【讨论】:

                【解决方案10】:
                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 将是正确的解决方案。

                【讨论】:

                • LinkedHashMap 中有什么方法可以使 LinkedHashmap 工作,而这段代码不能?
                【解决方案11】:

                在这里偶然发现相同的东西...然后我想起了 Guava library 中的 Iterables 类。

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

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

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

                请记住,虽然 HashMap 没有排序...所以不要指望 Iterables.getFirst 会返回您扔在那里的第一个项目...与Iterables.getLast 一样。 也许有用a 映射值。

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

                【讨论】:

                  【解决方案12】:

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

                  获取一个 ArrayList,然后对其进行转换并找到该 ArrayList 的大小。 这里是:

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

                  它会显示大小。 (提出建议)。它正在工作。

                  【讨论】:

                  • 如何从哈希映射中获取任意项?
                  【解决方案13】:

                  如果你使用的是Java 8,那么简单如findFirst():

                  快速示例:

                  Optional<Car> theCarFoundOpt = carMap.values().stream().findFirst();
                  
                  if(theCarFoundOpt.isPresent()) {
                      return theCarFoundOpt.get().startEngine();
                  }
                  

                  【讨论】:

                    【解决方案14】:
                    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;
                    

                    【讨论】:

                    • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
                    • 是的,请在您的代码中添加一些解释。
                    【解决方案15】:

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

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

                    【讨论】:

                      【解决方案16】:

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

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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2023-04-07
                        • 2017-05-24
                        相关资源
                        最近更新 更多