【问题标题】:Return the size of an ArrayList that is a value in a HashMap返回 ArrayList 的大小,它是 HashMap 中的一个值
【发布时间】:2014-03-10 04:29:26
【问题描述】:

我正在开发一个针对电子邮件客户端的垃圾邮件过滤器项目。

public MailServer()
{
    mailMap = new HashMap<String,ArrayList<MailItem>>();
}

我被指示使用 HashMap 来存储收件人,并使用 ArrayList 来保存他们的 mailItem。下一个方法是计算并返回特定收件人的 mailItems。

public int howManyMailItems(String who)
{
    int count = 0;
    for(MailItem item : mailMap) {
        if(item.getTo().equals(who)) {
            count++;
        }
    }
    return count;
}

编辑

我在 BlueJ 中工作,当我尝试编译该类时,它会在第 4 行突出显示 mailMap 并说

“for-each 循环不适用”

 public int howManyMailItems(String who)
{
    int count = 0;
    for(MailItem item : mailMap.keySet()) {
        if(item.getTo().equals(who)) {
            count++;
        }
    }
    return count;
}

当我尝试使用 keySet 时,它显示类型不兼容。

【问题讨论】:

  • 嗯...怎么了??你的问题到底是什么?
  • 我在 BlueJ 工作,当我尝试编译该类时,它会在第 4 行突出显示 mailMap 并说
  • "for-each 循环不适用"

标签: java arraylist hashmap


【解决方案1】:

Map 没有实现 Iterable 接口。这就是为什么您会收到“for-each 循环不适用”错误的原因。您可以选择遍历地图的

  • entrySet() — 一个Set&lt;Map.Entry&lt;K,V&gt;&gt;(其中K 是键类型,V 是映射的值类型);
  • keySet() — 一个Set&lt;K&gt;;或
  • values()Collection&lt;V&gt;

一般来说,你会想做这样的事情:

public int howManyMailItems(String who)
{
    int count = 0;
    for(Map.Entry<String,ArrayList<MailItem>> entry : mailMap.entrySet()) {
        String key = entry.getKey();
        ArrayList<MailItem> array = entry.getValue();
        // process key and array value
    }
    return count;
}

很难准确地说出您使用什么逻辑来计数。如果您只需要数组(并且忽略地图的键),那么您可以使用:

public int howManyMailItems(String who)
{
    int count = 0;
    for(ArrayList<MailItem> array : mailMap.values()) {
        for (MailItem item : array) {
            if (item.getTo().equals(who)) {
                count++;
            }
        }
    }
    return count;
}

附:使用接口而不是具体类型来声明泛型参数类型通常被认为是一种好的做法。例如,可以声明您的地图:

Map<String, List<MailItem>>

而不是

Map<String, ArrayList<MailItem>>

(您必须相应地修改迭代循环中使用的类型。)您仍然可以将ArrayList 的实例放入映射中,但您也可以改变主意并放入其他类型的List。 (例如,您可以将调用Collections.unmodifiableList(...) 产生的不可修改的列表放入。)

【讨论】:

    【解决方案2】:
    public int howManyMailItems(String who) {
        return mailMap.get(who).size();
    }
    

    【讨论】:

      【解决方案3】:

      您没有提及任何错误,因此很难知道出了什么问题,但通常您会遍历通过 keySet() 获得的 Map 的键集,或者通过通过 values() 获得的值。

      即,

      for(String key : mailMap.keySet()) {
          List<MainItem> itemList = mailMap.get(key);
          count += itemList.size(); // ??? not sure if this is what you want??
          // ... etc..
      }
      

      【讨论】:

      • public int howManyMailItems(String who) { mailMap int count = 0; for(MailItem item : mailMap.keySet()) { if(item.getTo().equals(who)) { count++; } } 返回计数;当我尝试编译时,它会突出显示 keySet 并说不兼容的类型
      • @TvDinnerGuy7:避免在评论中发布代码,因为它无法格式化且不可读。而是将其作为对您问题的编辑发布。
      【解决方案4】:

      正如你有HashMap&lt;String,ArrayList&lt;MailItem&gt;&gt;。键是String 的类型,值是ArrayList&lt;MailItem&gt;。您的错误原因是您获取列表并尝试将其分配给 MaiItem。

      public int howManyMailItems(String who)
      {
          int count = 0;
      
          if(who == null) { //Check the input before operate
            return count;
          }
      
          for(Iterable<MailItem> iterable : mailMap.values()) { //Interface instead of Class
              for (MailItem item : iterable) {
                  if (item == null) { //It is possible that item can be null
                     continue;
                  }
      
                  if (who.equals(item.getTo())) { //It is possible that To can be null
                      count++;
                  }
              }
          }
          return count;
      }
      

      为什么在 for-each 循环中使用 Iterable 而不是 ArrayList ?

      该解决方案的优势在于,我们不必更改我们决定使用另一个Collection 存储的代码。

      为什么 Iterable 不是 Collection ?

      在这种情况下,我们只执行读取操作,因此这是解决任务所需的最小值。这样做的好处是更大的代码灵活性。

      【讨论】:

        猜你喜欢
        • 2014-04-28
        • 1970-01-01
        • 2020-04-30
        • 1970-01-01
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 2018-05-16
        相关资源
        最近更新 更多