import java.io.*;
import java.util.*;

class CollDemo {
	static final int HOW_MANY = 20;

	public static void main(String [] args) throws Exception {
		int [] array = new int [HOW_MANY];
		ArrayList arrayList = new ArrayList();
		LinkedList linkedList = new LinkedList();
		Stack stack = new Stack();
		PriorityQueue priorityQueue = new PriorityQueue();
		HashSet hashSet = new HashSet();
		LinkedHashSet linkedHashSet = new LinkedHashSet();
		TreeSet treeSet = new TreeSet();

		Random random = new Random();

		for (int i = 0; i < HOW_MANY; i++) {
			Integer integer = new Integer(150+random.nextInt(40));
			array[i] = integer.intValue();
			arrayList.add(integer);
			linkedList.add(integer);
			stack.add(integer);
			priorityQueue.add(integer);
			hashSet.add(integer);
			linkedHashSet.add(integer);
			treeSet.add(integer);
		}

		System.out.print("====== The numbers (array): {");
		for (int i = 0; i < HOW_MANY; i++)
			System.out.print(array[i] + (i < HOW_MANY-1 ? ", " : ""));
		System.out.println("}");
		System.out.println();

		System.out.println("====== Printing using toString");

		print("arrayList", arrayList);
		print("linkedList", linkedList);
		print("stack", stack);
		print("priorityQueue", priorityQueue);
		print("hashSet", hashSet);
		print("linkedHashSet", linkedHashSet);
		print("treeSet", treeSet);
		System.out.println();

		System.out.println("====== Printing by iterating");

		iterPrint("arrayList", arrayList);
		iterPrint("linkedList", linkedList);
		iterPrint("stack", stack);
		iterPrint("priorityQueue", priorityQueue);
		iterPrint("hashSet", hashSet);
		iterPrint("linkedHashSet", linkedHashSet);
		iterPrint("treeSet", treeSet);
		System.out.println();


		System.out.println("====== Illustrating polymorphism on the parameter:");

		ArrayList arrayList2 = new ArrayList();
		for (int i = 1; i <= 10; i++)
			arrayList2.add(new Integer(1050+random.nextInt(12)));
		print("arrayList2", arrayList2);
		System.out.println();

		addAll(arrayList, arrayList2);
		addAll(linkedList, arrayList2);
		addAll(stack, arrayList2);
		addAll(priorityQueue, arrayList2);
		addAll(hashSet, arrayList2);
		addAll(linkedHashSet, arrayList2);
		addAll(treeSet, arrayList2);

		print("arrayList", arrayList);
		print("linkedList", linkedList);
		print("stack", stack);
		print("priorityQueue", priorityQueue);
		print("hashSet", hashSet);
		print("linkedHashSet", linkedHashSet);
		print("treeSet", treeSet);
		System.out.println();

		System.out.println("====== 'Modifying' the structure:");

		add_1("arrayList", arrayList);
		add_1("linkedList", linkedList);
		add_1("stack", stack);
		add_1("priorityQueue", priorityQueue);
		add_1("hashSet", hashSet);
		add_1("linkedHashSet", linkedHashSet);
		add_1("treeSet", treeSet);
		System.out.println();

		System.out.println("====== Printing the structures again:");

		print("arrayList", arrayList);
		print("linkedList", linkedList);
		print("stack", stack);
		print("priorityQueue", priorityQueue);
		print("hashSet", hashSet);
		print("linkedHashSet", linkedHashSet);
		print("treeSet", treeSet);
		System.out.println();
		System.out.println();

		System.out.println("====== Removing elements from the structures:");

		System.out.println("ArrayList (remove(0))");
		print("arrayList: ", arrayList);
		while (!arrayList.isEmpty())
			System.out.print(arrayList.remove(0) + " ");
		System.out.println();
		print("arrayList: ", arrayList);
		System.out.println();

		System.out.println("Stack (pop)");
		print("stack: ", stack);
		while (!stack.isEmpty())
			System.out.print(stack.pop() + " ");
		System.out.println();
		print("stack: ", stack);
		System.out.println();

		print("linkedList: ", linkedList);
		System.out.println("LinkedList (remove)");
		while (!linkedList.isEmpty())
			System.out.print(linkedList.remove() + " ");
		System.out.println();
		print("linkedList: ", linkedList);
		System.out.println();

		System.out.println("PriorityQueue (remove)");
		print("priorityQueue: ", priorityQueue);
		while (!priorityQueue.isEmpty())
			System.out.print(priorityQueue.poll() + " ");
		System.out.println();
		print("priorityQueue: ", priorityQueue);
		System.out.println();
		System.out.println();


		System.out.println("-------- Maps ---------");	

		HashMap hashMap = new HashMap();
		HashMap linkedHashMap = new LinkedHashMap();
		TreeMap treeMap = new TreeMap();

		Scanner scanner = new Scanner(new File("students.data"));

		System.out.println("Reading in the data and loading up the maps:");

		while (scanner.hasNext()) {
			String last = scanner.next();
			String first = scanner.next();
			String number = scanner.next();
			
			String name = last + ", " + first;

			hashMap.put(name, number);
			linkedHashMap.put(name, number);
			treeMap.put(name, number);

			System.out.println(last + " " + first + " " + number);
		}
		System.out.println();

		System.out.println("====== Printing using toString:");
		
		print("hashMap: ", hashMap);
		print("linkedHashMap: ", linkedHashMap);
		print("treeMap: ", treeMap);
		System.out.println();

		System.out.println("====== Printing by iterating (though the map's 'keyset'):");
		
		iterPrint("hashMap: ", hashMap);
		iterPrint("linkedHashMap: ", linkedHashMap);
		iterPrint("treeMap: ", treeMap);
		System.out.println();

		System.out.println("Using the map:");

		useMap("hashMap", hashMap, "Kellog, Jean");
		useMap("linkedHashMap", linkedHashMap, "Kellog, Jean");
		useMap("treeMap", treeMap, "Kellog, Jean");

		useMap("hashMap", hashMap, "Weiss, Gerald");
		useMap("linkedHashMap", linkedHashMap, "Weiss, Gerald");
		useMap("treeMap", treeMap, "Weiss, Gerald");

	}


	static void print(String name, Object object) {
		System.out.println(name + ": " + object);
	}

	static void iterPrint(String name, Iterable iterable) {
		System.out.print(name + ": ");
		for (Iterator iter = iterable.iterator(); iter.hasNext(); )	
			System.out.print(iter.next() +" ");
		System.out.println();
	}

	static void addAll(Collection coll1, Iterable iterable) {
		for (Iterator iter = iterable.iterator(); iter.hasNext(); )	
			coll1.add(iter.next());
	}

	static void add_1(String name, Collection coll) {
		System.out.print(name + ": ");
		for (Iterator iter = coll.iterator(); iter.hasNext(); ) {
			Integer integer = (Integer)iter.next();
			int i = integer.intValue();
			System.out.print((i+1) + " ");
		}
		System.out.println();
	}


	static void iterPrint(String name, Map map) {
		System.out.println(name + ": ");
		for (Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
			Object key = iter.next();
			Object value = map.get(key);
			System.out.println("\tkey: " + key + " value: " + value);
		}
		System.out.println();
	}

	static void useMap(String name, Map map, Object key) {
		System.out.println(name + " contains " + key + ": " + map.containsKey(key));
		System.out.println(name + ".get(" + key + "): " + map.get(key));
	}
}
