Вопрос

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.AbstractMap;

/**
 * A simple model of a mail server. The server is able to receive
 * mail items for storage, and deliver them to clients on demand.
 */
 public class MailServer
 {
    // Storage for the arbitrary number of mail items to be stored
    // on the server.
    private HashMap<String,ArrayList<MailItem>> mailMap;

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

    /**
     * Return how many mail items are waiting for a user.
     */
    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;
    }

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

    /**
     * Return the next mail item for a user or null if there
     * are none.
     */
    public MailItem getNextMailItems(String who, int howMany)
    {
        // Access the ArrayList for "who" remove and return the first element
        // Be careful what if "who" doesn't have an entry in the mailMap
        // Or what if "who" doesn't have any mail?
        Iterator<Map.Entry<String, ArrayList<MailItem>>> it = 
        mailMap.entrySet().iterator();
        while(it.hasNext()) {
            Map.Entry<String, ArrayList<MailItem>> entry = it.next();
            String key = entry.getKey();
            ArrayList<MailItem> value = entry.getValue();
            if (key.equals(who));
            {
                return value.remove(0);
            }
        }
        return null;
    }

    /**
     * Add the given mail item to the message list.
     */
    public void post(String who)
    {
        if (mailMap.containsKey(who)) {
            Map.put(who, Map.get(who) + 1);
        }

    }
}

The above code is for a basic mail server. I was attempting to make it store a MailItem(String recipient, String subject, String message) in a HashMap with a String key and an ArrayList (of MailItems) value.

What I am having trouble with is the post() method. I can't figure out how to make it take the parameter of who the message is intended for and store it in the corresponding ArrayList.

I am also having problems with the getNextMailItems() method. I can't figure out how to make it return multiple items from the ArrayList of the recipient. All I have been able to figure out is to add a parameter specifying how many MailItems to return.

I am incredibly inexperienced with java and am still learning. Please help. Thank you all.

Это было полезно?

Решение

Since you are learning Java, let me point out a few things:

  • Please try the Guava MultiMap instead of the much uglier:

    private HashMap<String,ArrayList<MailItem>> mailMap;
    

    Also try to use interfaces instead of classes, i.e., Map<String,List<MailItem> would be better because it does not tie you to the particular implementation.

  • This is not optimal and I suspect wrong:

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

    you should call get(who) on the map and if you get a non null list, you will have a list of MailItems for who. Then calling List.size() will give you the count (I suspect) you need.

  • Two notes about this block of code:

    Iterator<Map.Entry<String, ArrayList<MailItem>>> it = mailMap.entrySet().iterator();
    while(it.hasNext()) {
      Map.Entry<String, ArrayList<MailItem>> entry = it.next();
      String key = entry.getKey();
      ArrayList<MailItem> value = entry.getValue();
      if (key.equals(who)); // the semicolon here means that if the condition is true, do nothing
      {
        return value.remove(0); // this block is ALWAYS EXECUTED
      }
    }
    return null;
    

    If the condition in the if is true, nothing will be executed because of the semicolon and the code in the code block will always be executed the first time. That said, once again you are given the key, so you don't need to loop through the whole map (see previous point). However, if you want to iterate a map please use the more compact idiom:

    for(Map.Entry<String,ArrayList<MailItem>> e : mailMap.entrySet()){
      // do something with the key and value, e.getKey(), e.getValue()
    }
    
  • Finally, this block is puzzling:

    if (mailMap.containsKey(who)) {
      Map.put(who, Map.get(who) + 1);
    }
    

    what are you trying to do? Map is the name of an interface and doesn't have static methods put or get so that won't even compile. If you were trying to add an element to mailMap for the key who then you probably want something like (typical idiom for map of lists, again see Guava for a better API):

    ArrayList<MailItem> l = mailMap.get(who);
    if(l == null){ // this super verbose code will simplify with the Guava MultiMap
      l = new ArrayList<MailItem>();
      mailMap.put(who, l);
    }
    l.add(/* code to create a new MailItem */);
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top