【问题标题】:How to add element into ArrayList in HashMap如何将元素添加到 HashMap 中的 ArrayList
【发布时间】:2012-08-26 23:20:07
【问题描述】:

如何在HashMap的ArrayList中添加元素?

    HashMap<String, ArrayList<Item>> Items = new HashMap<String, ArrayList<Item>>();

【问题讨论】:

    标签: java data-structures


    【解决方案1】:

    我知道,这是一个老问题。但只是为了完整起见,lambda 版本。

    Map<String, List<Item>> items = new HashMap<>();
    items.computeIfAbsent(key, k -> new ArrayList<>()).add(item);
    

    【讨论】:

    • 这很好用。因为computeIfAbsent()是为了实现一个多值映射,Map>,每个key支持多个值
    • 有史以来最好的解决方案。
    • 有人!!给这家伙一枚奖章。
    • 干得好,这很干净,应该被接受。
    • 这个答案解决了我的问题。但我很好奇怎么做。我有一个逻辑,我根据键显式检查值,然后进行插入。由于我使用的是 spring webflux,多个线程正在访问此地图并给出不一致的结果。我尝试使用同步映射和并发哈希映射,但都失败了。最后上面的 computeIfAbsent 工作,我不知道为什么。即使是 computeIfAbsent 文档也没有提到任何关于并发写入成功保证的内容。我已经测试了我的新代码 N 次并且它有效。只是我担心它可能会破坏 Prod
    【解决方案2】:
    HashMap<String, ArrayList<Item>> items = new HashMap<String, ArrayList<Item>>();
    
    public synchronized void addToList(String mapKey, Item myItem) {
        List<Item> itemsList = items.get(mapKey);
    
        // if list does not exist create it
        if(itemsList == null) {
             itemsList = new ArrayList<Item>();
             itemsList.add(myItem);
             items.put(mapKey, itemsList);
        } else {
            // add if item is not already in list
            if(!itemsList.contains(myItem)) itemsList.add(myItem);
        }
    }
    

    【讨论】:

    • 正如我在回答中指出的那样,这是非常不安全的,但是,如果您确定这不是问题,它会正常工作。
    • 我认为数据结构是所要求的,但是为了多线程,让我们添加一个同步的。
    • 地图界面有一个方便的合并功能docs.oracle.com/javase/8/docs/api/java/util/…
    【解决方案3】:

    首先你必须添加一个 ArrayList 到 Map

    ArrayList<Item> al = new ArrayList<Item>();
    
    Items.add("theKey", al); 
    

    然后您可以像这样向 Map 内的 ArrayLIst 添加一个项目:

    Items.get("theKey").add(item);  // item is an object of type Item
    

    【讨论】:

    • 将ArrayList添加到Map的方法不会是'put'而不是'add'吗?
    【解决方案4】:

    典型的代码是创建一个显式的方法来添加到列表中,并在添加时动态创建ArrayList。请注意同步,因此列表只会创建一次!

    @Override
    public synchronized boolean addToList(String key, Item item) {
       Collection<Item> list = theMap.get(key);
       if (list == null)  {
          list = new ArrayList<Item>();  // or, if you prefer, some other List, a Set, etc...
          theMap.put(key, list );
       }
    
       return list.add(item);
    }
    

    【讨论】:

    • synchronized 标志在这里真的有用吗? ArrayList 和大多数标准集合都不是线程安全的,所以确保这个块是同步的并不是那么有用,对吧?
    • 它确保 ArrayList 只创建一次。而且,如果这是您添加到列表的唯一位置,那么它将受到保护。但是,在复杂的情况下,如果您真的想要线程安全,请在item = new ... line 上使用除ArrayList 之外的其他内容,例如CopyOnWriteArrayList 等...
    • 我认为这里有错误。第 4 行、第 5 行和第 6 行中说“item”的所有地方都应该说“list”
    • 哇——一个持续了一年多的大错误。很好地抓住麦克!代码已更正。
    【解决方案5】:
    #i'm also maintaining insertion order here
    Map<Integer,ArrayList> d=new LinkedHashMap<>();
    for( int i=0; i<2; i++)
    {
    int id=s.nextInt();
    ArrayList al=new ArrayList<>();
    al.add(s.next());  //name
    al.add(s.next());  //category
    al.add(s.nextInt()); //fee
    d.put(id, al);
     }
    

    【讨论】:

    • 这看起来与我的问题无关
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多