MailingList.java

package mailinglist;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * A collection of names and addresses
 */
public class MailingList implements Cloneable, Iterable<Contact> {

    private LinkedList<Contact> theContacts;

    /**
     * Create an empty mailing list
     *
     */
    public MailingList() {
        theContacts = new LinkedList<Contact>();
    }

    /**
     *  Add a new contact to the list. Contacts should be kept in ascending
     *  order with no duplicates.
     *  
     *  @param contact new contact to add
     */
    public void addContact(Contact contact) {
        ListIterator<Contact> it = theContacts.listIterator();
        while (it.hasNext()) {
            Contact c = it.next();
            int compared = c.compareTo(contact); 
            if (compared > 0) {
                it.previous();
                it.add(contact);
                return;
            } else if (compared == 0) {
                return;
            }
        }
        theContacts.add(contact);
    }

    /**
     *  Remove one matching contact 
     *  @param contact remove a contact equal to contact
     */
    public void removeContact(Contact contact) {
        ListIterator<Contact> it = theContacts.listIterator();
        while (it.hasNext()) {
            Contact c = it.next();
            int compared = c.compareTo(contact); 
            if (compared > 0) {
                return;
            } else if (compared == 0) {
                it.remove();
                return;
            }
        }
    }

    /**
     * Remove a contact with the indicated name
     * @param name name of contact to remove
     */
    public void removeContact(String name) {
        ListIterator<Contact> it = theContacts.listIterator();
        while (it.hasNext()) {
            Contact c = it.next();
            int compared = c.getName().compareTo(name); 
            if (compared > 0) {
                return;
            } else if (compared == 0) {
                it.remove();
                return;
            }
        }
    }

    /**
     * Search for contacts
     * @param name name to search for
     * @return true if a contact with an equal name exists
     */
    public boolean contains(String name) {
        ListIterator<Contact> it = theContacts.listIterator();
        while (it.hasNext()) {
            Contact c = it.next();
            int compared = c.getName().compareTo(name); 
            if (compared > 0) {
                return false;
            } else if (compared == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * Search for contacts
     * @param name name to search for
     * @return contact with that name if found, null if not found
     */
    public Contact getContact(String name) {
        ListIterator<Contact> it = theContacts.listIterator();
        while (it.hasNext()) {
            Contact c = it.next();
            int compared = c.getName().compareTo(name); 
            if (compared > 0) {
                return null;
            } else if (compared == 0) {
                return c;
            }
        }
        return null;
    }

    /**
     * combine two mailing lists
     *
     */
    public void merge(MailingList anotherList) {
       // For a quick merge, we will loop around, checking the 
       // first item in each list, and always copying the smaller
       // of the two items into result
       LinkedList<Contact> result = new LinkedList<Contact>();
       ListIterator<Contact> thisPos = theContacts.listIterator();
        ListIterator<Contact> otherPos = anotherList.theContacts.listIterator();
        while (thisPos.hasNext() && otherPos.hasNext()) {
            Contact thisContact = thisPos.next();
            Contact otherContact = otherPos.next();
            int comp = thisContact.compareTo(otherContact);
            if (comp == 0) {
                result.add(thisContact);
            } else if (comp < 0) {
                result.add(thisContact);
                otherPos.previous();
            } else {
                result.add(otherContact);
                thisPos.previous();
            }           
        }
        // Now, one of the two lists has been entirely copied. 
        // The other might still have stuff to copy. So we just copy
        // any remaining items from the two lists. Note that one of these
        // two loops will execute zero times.
        while (thisPos.hasNext()) {
            result.add(thisPos.next());
        }
        while (otherPos.hasNext()) {
            result.add(otherPos.next());
        }
        // Now result contains the merged list. Transfer that into this list.
       theContacts = result;
    }

    /**
     * How many contacts in list?
     */
    public int size() {
       return theContacts.size();
    }

    /**
     * Return true if mailing lists contain equal contacts
     */
    public boolean equals(Object anotherList) {
        if (!(anotherList instanceof MailingList)) {
            return false;
        }
       MailingList right = (MailingList) anotherList;
       if (size() != right.size()) { // (easy test first!)
         return false;
       }
        ListIterator<Contact> thisPos = theContacts.listIterator();
        ListIterator<Contact> otherPos = right.theContacts.listIterator();
        while (thisPos.hasNext() && otherPos.hasNext()) {
            Contact thisContact = thisPos.next();
            Contact otherContact = otherPos.next();
            if (!thisContact.equals(otherContact)) {
                return false;
            }
        }
        return true;
    }

    public int hashCode() {
        return theContacts.hashCode();
    }

    public String toString() {
       StringBuffer buf = new StringBuffer("{");
       boolean first = true;
       for (Contact c: theContacts) {
           if (!first) {
               buf.append(", ");
           }
           first = false;
           buf.append(c.toString());
       }
       buf.append("}");
       return buf.toString();
    }

    /**
     * Deep copy of contacts
     */
    public Object clone() {
       MailingList result = new MailingList();
       for (Contact c: theContacts) {
           result.theContacts.add((Contact)c.clone());
       }
       return result;
    }


    /**
     * Provide access to the contacts.
     */
    @Override
    public Iterator<Contact> iterator() {
        return theContacts.iterator();
    } 

}

unformatted source