简体   繁体   English

返回作为HashMap中值的ArrayList的大小

[英]Return the size of an ArrayList that is a value in a HashMap

I am working on project that is a spam filter for an email client. 我正在开发一个项目,它是电子邮件客户端的垃圾邮件过滤器。

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

I was instructed to use a HashMap to store the recipients and ArrayLists to hold their mailItems. 我被指示使用HashMap存储收件人和ArrayLists来保存他们的mailItems。 The next method is to count and return the mailItems for a specific recipient. 下一个方法是计算并返回特定收件人的mailItems。

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

Edit 编辑

I'm working in BlueJ and when I try to compile the class it highlights mailMap in the 4th line and says 我在BlueJ工作,当我尝试编译该类时,它在第4行突出显示了mailMap并说

"for-each loop not appicable" “for-each循环不适合”

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

When I try a keySet it says incompatible types. 当我尝试使用keySet时,它会说不兼容的类型。

A Map does not implement the Iterable interface. Map不实现Iterable接口。 This is why you get the "for-each loop not appicable" error. 这就是为什么你得到“for-each loop not appicable”错误。 You have a choice of iterating over the map's 您可以选择迭代地图

  • entrySet() — a Set<Map.Entry<K,V>> (where K is the key type and V is the value type of the map); entrySet() - 一个Set<Map.Entry<K,V>> (其中K是键类型, V是地图的值类型);
  • keySet() — a Set<K> ; keySet() - 一个Set<K> ; or 要么
  • values() — a Collection<V> . values() - Collection<V>

In general, you would want to do something like this: 一般来说,你会想要做这样的事情:

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

It's hard to tell exactly what logic you are using to count. 很难确切地告诉你用什么逻辑来计算。 If you only need the arrays (and are ignoring the keys to your map), then you can use: 如果您只需要数组(并忽略地图的键),那么您可以使用:

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

PS It's generally considered good practice to declare generic parameter types using interfaces rather than concrete types. PS通常认为使用接口而不是具体类型声明泛型参数类型是一种好习惯。 For instance, your map could be declared: 例如,您的地图可以声明:

Map<String, List<MailItem>>

rather than 而不是

Map<String, ArrayList<MailItem>>

(You would have to modify the type used in the iteration loop accordingly.) You can still put instances of ArrayList into the map, but you could also change your mind and put other kinds of List . (您必须相应地修改迭代循环中使用的类型。)您仍然可以将ArrayList实例放入地图中,但您也可以改变主意并添加其他类型的List (For instance, you could then put unmodifiable lists resulting from calls to Collections.unmodifiableList(...) .) (例如,您可以放置​​由Collections.unmodifiableList(...)调用产生的不可修改的列表。)

public int howManyMailItems(String who) {
    return mailMap.get(who).size();
}

You're not mentioning any errors, so it's tough to know what's wrong, but usually you iterate through a Map's Key Set, obtained via keySet() , or through its values obtained via values() . 你没有提到任何错误,所以很难知道什么是错的,但通常你会遍历一个Map的Key Set,通过keySet()或通过values()获得的values()

ie,

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

As you have HashMap<String,ArrayList<MailItem>> . 因为你有HashMap<String,ArrayList<MailItem>> The key is type of String and value is ArrayList<MailItem> . 键是String类型,值是ArrayList<MailItem> The reason of your error is that you fetch the List and try to assign it to MaiItem. 您输入错误的原因是您获取List并尝试将其分配给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;
}

Why to use Iterable instead of ArrayList in for-each loop ? 为什么在for-each循环中使用Iterable而不是ArrayList?

The advantage of that solution is that, we do not have to change the code we decide to use another Collection for our storage. 该解决方案的优点是,我们不必更改我们决定使用另一个Collection进行存储的代码。

Why Iterable not Collection ? 为什么Iterable没有收藏?

In this case we perform only read operation, so this is the required minimum to solve the task. 在这种情况下,我们只执行读操作,因此这是解决任务所需的最小值。 The advantage of this is greater code flexibility. 这样做的好处是更大的代码灵活性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM