// Help Maps
import java.util.*;


public class Main // HelpMaps
{

  // ***** main method *****
  public static void main(String[] arguments)
  {
      System.out.printf("Hello Maps - TreeMap and HashMap");
      System.out.printf("%n");
      System.out.printf("\n");

      // Stores data in an internal private object.
      // You can NOT USE [] to access the data!!!
      // There are NO INDEXES!!!!!

      // NO DUPLICATE Keys!   
      // Use a TreeMap if you want your map sorted (ordered) by the Key.
      // Use a HashMap if you don't need it ordered.
      
      // The TreeMap and HashMap will only hold objects, 
      // and for this case I have specified only Integer objects.

      // Example: Key and value
      // Maps have keys and value pairs.
      // TreeMap<Integer,Integer> map1 = new TreeMap<Integer,Integer>();
      // HashMap<Integer,Integer> map2 = new HashMap<Integer,Integer>();
      
      // The new part creates a new TreeMap or HashMap object 
      // which holds the data.
      
      // The TreeMap<Integer,Integer>() calls the constructor 
      // to initialize
      // the instance variables of the TreeMap object.
      
      // The variable map1 will receive the memory address of the
      // TreeMap object.

      // The variable map2 will receive the memory address of the
      // HashMap object.
      
      TreeMap<Integer,Integer> map1 = new TreeMap<Integer,Integer>(); // or use <>
      
      // Map methods:
      // put(key, value)
      // get(key)
      // clear()
      // size()
      // keySet()
      // containsKey(key)
      // values()

      // Maps have key and value pairs.
      // 0 is the key, 5 is the value.
      System.out.println("Adding key 0 and value 5 returning: " + map1.put(0,5));
      
      System.out.println("Adding key 1 and value 7 returning: " + map1.put(1,7));

      System.out.println("Adding key 2 and value 7 returning: " + map1.put(2,7));

      System.out.println("Adding key 3 and value 8  returning: " + map1.put(3,8));

      System.out.println("Adding key 3 and value 90 returning: " + map1.put(3,90));

      System.out.println();

      System.out.println("map1 printing by calling toString() method:");      
      System.out.println(map1); 
      System.out.println();

      System.out.println("map1 printing by calling keySet() method:");      
      System.out.println(map1.keySet()); 
      System.out.println();

      System.out.println("map1 printing by calling values() method:");      
      System.out.println(map1.values()); 
      System.out.println();

      System.out.println("map1 contains by calling containsKey() method:");      
      System.out.println("containsKey(2) returns: " + map1.containsKey(2)); 
      System.out.println();
      
      // printing a map
      // You can call toString() or use a for each loop
      // REMEMBER THERE ARE NO INDEXES
      
      System.out.println("Printing the items in map1 with a for each loop.");
      for (Integer key : map1.keySet())
      {
          System.out.print(key + " ");
          System.out.print(map1.get(key) + " - ");
      }
      

      System.out.println();
      System.out.println();
 

      // You can also use an Iterator 
      // The Iterator object has three methods:
      // (there is also a ListIterator which has 
      //  additional methods)
      // hasNext() - boolean, true you have another object else false
      // next() - gives you a copy of the item (or memory address)
      // remove() - removes the item that you just retrieved.
      
      Iterator<Integer> it = map1.keySet().iterator();

      System.out.println("Printing the items in map1 with an Iterator");
      while (it.hasNext())
      {
          Integer key = it.next(); 
          System.out.print(key + " ");
          System.out.print(map1.get(key) + " - ");
      }
      System.out.println();

      it = map1.keySet().iterator();

      System.out.println("removing an item from map1");
      System.out.println("and removing key 2");
      while (it.hasNext())
      {
          Integer key = it.next();
           
          if (key == 2)
          {
            it.remove();
          }
      }
      
      System.out.println();

      it = map1.keySet().iterator();

      System.out.println("Printing the items in map1 with an Iterator");
      while (it.hasNext())
      {
          Integer key = it.next(); 
          System.out.print(key + " ");
          System.out.print(map1.get(key) + " - ");
      }
      
      System.out.println();
      System.out.println();
      System.out.println("HashMap Example");
      System.out.println();
      System.out.println();


      // Example with HashMap:
      HashMap<Integer,String> map2 = new HashMap<Integer,String>(); // or use <>

      System.out.println("Adding key 67085 and value Tom returning: " + map2.put(67085,"Tom"));
      
      System.out.println("Adding key 54567 and value Sue returning: " + map2.put(54567,"Sue"));

      System.out.println("Adding key 97823 and value Mary returning: " + map2.put(97823,"Mary"));

      System.out.println("Adding key 97823 and value Jill returning: " + map2.put(97823,"Jill"));

      System.out.println();

      System.out.println("map2 printing by calling toString() method:");      
      System.out.println(map2); 
      System.out.println();

      System.out.println("map2 printing by calling keySet() method:");      
      System.out.println(map2.keySet()); 
      System.out.println();

      System.out.println("map2 printing by calling values() method:");      
      System.out.println(map2.values()); 
      System.out.println();

      System.out.println("map2 contains by calling containsKey() method:");      
      System.out.println("containsKey(97823) returns: " + map2.containsKey(97823)); 
      System.out.println();

      System.out.println("Printing the items in map2 with a for each loop.");
      for (Integer key : map2.keySet())
      {
          System.out.print(key + " ");
          System.out.print(map2.get(key) + " - ");
      }
      

      System.out.println();
      System.out.println();
 

      // You can also use an Iterator 
      // The Iterator object has three methods:
      // (there is also a ListIterator which has 
      //  additional methods)
      // hasNext() - boolean, true you have another object else false
      // next() - gives you a copy of the item (or memory address)
      // remove() - removes the item that you just retrieved.
      
      it = map2.keySet().iterator();

      System.out.println("Printing the items in map2 with an Iterator");
      while (it.hasNext())
      {
          Integer key = it.next(); 
          System.out.print(key + " ");
          System.out.print(map2.get(key) + " - ");
      }
      System.out.println();


      System.out.println();
      System.out.println();

  }



} // end of class HelpMaps


