【问题标题】:How to get position of key/value in LinkedHashMap using its key如何使用其键获取 LinkedHashMap 中键/值的位置
【发布时间】:2012-05-10 08:46:27
【问题描述】:

我有一个 LinkedHashMap(称为 info),其中包含名称/年龄(字符串/整数)对。如果我输入键,如何获得键/值的位置?例如,如果我的LinkedHashMap 看起来像这样{bob=12, jeremy=42, carly=21} 并且我要搜索jeremy,它应该返回1 作为它的位置1。我希望我可以使用类似info.getIndex("jeremy") 的东西。

【问题讨论】:

标签: java linkedhashmap


【解决方案1】:

考虑到 LinkedHashMap 保持插入顺序,您可以像这样使用 keySet() 和 List.copyOf()(Java 10 起)方法:

List<String> keys = List.copyOf( yourLinkedHashMap.keySet() );

System.out.println( keys.indexOf("jeremy") ); // prints '1'

【讨论】:

    【解决方案2】:

    我确实将键的位置提取到一个并发映射中,如下所示:

    对于 Map,someListOfComplexObject() 将是 entrySet() 而 getComplexStringKeyElem() 将是 getKey()

    可能来自

     final int[] index = {0};
     Stream<ComplexObject> t = someListOfComplexObject.stream();
     ConcurrentMap<String, List<Integer>> m = 
          t.collect(Collectors.groupingBy(
               e -> e.getComplexStringKeyElem(),
               Collectors.mapping(
                    e -> index[0]++,
                    Collectors.toList()
               ),
               ConcurrentSkipListMap::new));
    

    【讨论】:

      【解决方案3】:

      我在

      看到了来自此问题的重复项之一的建议

      How get value from LinkedHashMap based on index not on key?

      我喜欢 cmets 中 @schippi 的伪代码所描述的建议。我认为一些有效的 Java 代码可能对其他人有用

      import java.util.ArrayList;
      import java.util.LinkedHashMap;
      
      public class IndexedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
      
          /**
           * 
           */
          private static final long serialVersionUID = 1L;
      
          ArrayList<K> al_Index = new ArrayList<K>();
      
          @Override
          public V put(K key,V val) {
              if (!super.containsKey(key)) al_Index.add(key);
              V returnValue = super.put(key,val);
              return returnValue;
          }
      
          public V getValueAtIndex(int i){
              return (V) super.get(al_Index.get(i));
          }
      
          public K getKeyAtIndex(int i) {
              return (K) al_Index.get(i);
          }
      
          public int getIndexOf(K key) {
              return al_Index.indexOf(key);
          }
      
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用 Google Guava 库中的com.google.common.collect.LinkedListMultimap。你不需要这个类的多映射行为你想要的是keys()方法保证它们按插入顺序返回,然后可以用来构造一个List,你可以使用indexOf()找到所需的索引位置

        【讨论】:

          【解决方案5】:
          int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy")
          

          【讨论】:

          【解决方案6】:

          HashMap 的实现通常对于Iteration 是无序的。

          LinkedHashMappredictablelyIteration (插入顺序)订购的,但不公开List 接口和LinkedList(这反映了键集插入顺序)确实也不跟踪索引位置本身,查找索引也非常低效。 LinkedHashMap 也不公开对内部 LinkedList 的引用。

          实际的“链接列表” 行为是特定于实现的。一些 实际上可能会使用LinkedList 的一个实例,有些人刚刚拥有 Entry 跟踪上一个和下一个 Entry 并将其用作 执行。不看源头,不要假设任何事情。

          包含键的KeySet 也不能保证顺序,因为散列算法用于放置在继承的HashMap 的支持数据结构中。所以你不能使用它。

          在不编写自己的实现的情况下执行此操作的唯一方法是遍历使用镜像LinkedListIterator 并保持计数,这对于大型数据集将非常低效。

          解决方案

          听起来您想要的是原始插入订单索引位置,您必须将KeySet 中的键映射为ArrayList,使其与更新保持同步HashMap 并将其用于查找位置。创建一个HashMap 的子类,比如IndexedHashMap 并在内部添加这个ArrayList 并添加一个代表内部ArrayList.getKeyIndex(&lt;K&gt; key) .indexOf() 可能是解决这个问题的最佳方法。

          这就是LinkedHashMap 所做的,但LinkedList 镜像KeySet 而不是ArrayList

          【讨论】:

          • 我认为 LinkedHashMap 保留了顺序。有什么我可以使用可以存储键/值但保留顺序的东西吗?
          • 它保留,order,但不跟踪position
          • @HernánEche 阅读了问题和答案以便理解,他们也想跟踪位置,我在回答中对此进行了详细介绍。
          • @HernánEche HashSetorder 可以 在每次插入或删除时更改,不能保证,所以是的,我是正确的,你不能用那个!
          【解决方案7】:

          LinkedHashMap 具有“可预测的迭代顺序”(javadoc)。但是,项目不知道它们的位置,因此您必须迭代集合才能获得它。如果您要维护大型地图,则可能需要使用不同的存储结构。

          编辑:澄清迭代

          【讨论】:

          • *"走钥匙Set对你没有任何好处,它有Set支持,它是无序的。LinkedList仅用于@ 987654326@.When in doubt use the source.
          • 确实如此。我的意思是入口集。这就是为什么引用迭代顺序位......暗示迭代器的使用。我选词不当。
          • javadoc 中的第一段说它是按插入顺序排列的,这正是他所要求的。无论如何,我认为我们在这里说的是同一件事。编辑使您的答案更加清晰。
          • 他们希望按插入顺序按 key 的位置,如果不使用 Iterator 和股票 LinkedHashMap,您将无法获得该位置。 keyset 或 entryset 都不会单独提供他们所要求的内容。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-28
          • 1970-01-01
          • 2014-02-20
          • 2011-03-28
          相关资源
          最近更新 更多