package jcf_set.exercise;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class IteratoreSenzaDuplicati {
	
	public static void main(String[] main) {
		new IteratoreSenzaDuplicati().run();
	}
	
	public void run() {
		
		List<String> lista = new ArrayList<String>();
		
		lista.add("tree");
		lista.add("flower");
		lista.add("tree");
		lista.add("flower");
		lista.add("animal");
		lista.add("flower");
		lista.add("fruit");
		
		// Stampa collections
		System.out.println("Lista con duplicati: ");
		System.out.println(lista);
		System.out.println();
		
		// Test metodi privati 
		List<String> testList = new LinkedList<String>();
		
		Iterator<String> itNoDup = getIteratorNoDuplicates(lista.iterator());
		while (itNoDup.hasNext()) testList.add(itNoDup.next());
		
		System.out.println("Lista senza duplicati: ");
		System.out.println(testList);
		System.out.println();
		
		testList = new LinkedList<String>();
		System.gc();
		
		Iterator<String> itNoDupOrd = getIteratorNoDuplicatesOrdinated(lista.iterator());
		while (itNoDupOrd.hasNext()) testList.add(itNoDupOrd.next());
		
		System.out.println("Lista senza duplicati ordinata: ");
		System.out.println(testList);
	}
	
	// Esercizio 1
	/*
	 * Passare una lista con duplicati.
	 * Ottenere un iteratore privo di duplicati.
	 */
	private static <T extends Comparable<? super T>> Iterator<T> getIteratorNoDuplicates(Iterator<T> it) {
		HashSet<T> tmp = new HashSet<T>();
		while (it.hasNext()) tmp.add(it.next());
		return tmp.iterator();
	}
	
	// Esercizio 2
	/*
	 * Passare come parametro una lista con duplicati.
	 * Ottenere un iteratore senza duplicati e ordinato.
	 */
	private static <T extends Comparable<? super T>> Iterator<T> getIteratorNoDuplicatesOrdinated(Iterator<T> it) {
		TreeSet<T> tmp = new TreeSet<T>();
		while (it.hasNext()) tmp.add(it.next());
		return tmp.iterator();
	}
	
	// Esercizio 3
	/*
	 * Usare la classe TreeSet per eliminare i duplicati
	 * da un iteratore su una struttura di elementi che implementano 
	 * Comparable<E>, restituendo in output un iteratore che scorre
	 * i dati secondo l'ordine indotto dal metodo compareTo();
	 */
	public static <E extends Comparable >
	
}
