package yi.ds;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.*;
import java.io.*;

/**
 * The elements of LinkedListHashMap are LinkedList
 */

public class LinkedListHashMap extends HashMap{

  static final long serialVersionUID =  -86010322141676735L;

  public LinkedListHashMap() {
  }

  public void addToList(Object key, Object list_element) {
    LinkedList value = null;
    if (containsKey(key)) {
      value = (LinkedList)get(key);
    } else {
      value = new LinkedList();
      put(key, value);
    }
    value.add(list_element);
  }

  /**
   * Add the elements in the linkedlist in the given LinkedListHashMap into
   * that of this object
   * @param llhm
   */
  public void addAllInDeep(LinkedListHashMap llhm) {
    for (Iterator i=llhm.keySet().iterator(); i.hasNext(); ) {
      Object key1 = i.next();
      LinkedList list2 = llhm.getList(key1);
      if (containsKey(key1)) {
        LinkedList list1 = getList(key1);
        list1.addAll(list2);
      } else {
        put(key1, list2);
      }
    }
  }

  public LinkedList getList(Object key) {
    return (LinkedList)get(key);
  }

  /**
   * Return the total of the element size in all the linked list
   * @return
   */
  public int deepSize() {
    int size = 0;
    for (Iterator i=keySet().iterator(); i.hasNext(); ) {
      Object key1 = i.next();
      LinkedList list2 = getList(key1);
      size += list2.size();
    }
    return size;
  }

  public String toString() {
    StringWriter str = new StringWriter();
    PrintWriter out = new PrintWriter(str);

    ArrayList keys = new ArrayList(keySet());
    Collections.sort(keys);
    for (Iterator i=keys.iterator(); i.hasNext(); ) {
      Object key = i.next();
      out.print(key.toString() + "->{");
      LinkedList list = (LinkedList)get(key);
      boolean first = true;
      for (Iterator j=list.iterator(); j.hasNext(); ) {
        if (first) {
          first = false;
        } else {
          out.print(";");
        }
        out.print(j.next());
      }
      out.println("}");
    }
    return str.toString();
  }
}