如何创建由 Map 支持的可变列表

How do I create a mutable List backed by Map

提问人:Igor Golovin 提问时间:5/26/2018 最后编辑:Igor Golovin 更新时间:5/3/2021 访问量:1259

问:

如果我有将值映射到键的方法,我该如何返回一个支持者?List<E>Map<K, E>MapvalueToKeyMapper

class Foo {
   private Map<Integer, String> backedMap = new HashMap<Integer, String>();

   public List<String> getList() {
      // NEED TO RETURN LIST BACKED BY MAP
   }

   public String getById(Integer id) {
      return backedMap.get(id);
   }

   private static Integer valueToKeyMapper(String value) {
      // just as exampl. In reality value will be POJO with method like getId()
      return value.hashCode();
   }
}

代码应如下所示(简单示例):

Foo foo = new Foo();
foo.getList().add("something");
String value = foo.getById("something".hashCode());
// I should see something

笔记:

  • List应该是可变的,并且更改必须在底层中传播Map
  • 我无法修改对象的公共方法,因为它用于其他项目Foo
  • 我不在乎顺序List
  • 该方法应继续快速工作getById
爪哇岛 列表 字典 装饰 可变

评论

1赞 JustinKSU 5/26/2018
如果添加到列表中,地图中应该包含什么?
1赞 JB Nizet 5/26/2018
您似乎认为哈希码是唯一的 ID。他们不是。不要这样对待他们。
1赞 Igor Golovin 5/26/2018
将值添加到列表中时,应按如下方式修改地图:map.put(Foo.valueToKeyMapper(value), value)
1赞 Igor Golovin 5/26/2018
hashCodes只是为了breverty,实际上是一个有方法的业务对象valuevalue.getId()
1赞 Antoniossss 5/26/2018
我不在乎列表中的顺序那么你不需要,但无论如何都会得到支持。ListSetHashSetHashMap

答:

0赞 Sumit 5/26/2018 #1

试试这样的东西:---


List<String> list = new ArrayList<>();  

Set keys = backedMap.keySet();
for (Iterator i = keys.iterator(); i.hasNext(); ) {
           Integer key = (Integer) i.next();
           String value = (String) backedMap.get(key);
           list.add(value);
       }


 //To print Values in ArrayList :--    
    for(String s : list) {
              System.out.println("printing element -- " + s);
          }
0赞 Igor Golovin 5/26/2018 #2

在 github 上使用它的尝试:ListBackedByMap.javaList

它使用 ForwardingList 在地图中维护列表的内部副本。

我发现这个 impl 有两个问题:

  1. 它在内存中维护元素的额外副本
  2. 它不会尝试在迭代器中修改列表。ConcurrentModificationException

此处提供测试。