package jcf_set.exercise;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Insiemistica {
	
	public static void main(String[] main) {
		
		// Insiemi di test
		Integer[] aArray = {1, -2, 3, -4, 3};
		Integer[] bArray = {1, 5, -6, -4, 5};
		
		// Input come HashSet (Ordine non garantito)
		Set<Integer> aHashSet = new HashSet<Integer>(Arrays.asList(aArray));
		Set<Integer> bHashSet = new HashSet<Integer>(Arrays.asList(bArray));
		
		// Stampa delle due collezioni
		System.out.println("Stampa della collezone a: ");
		System.out.println(aHashSet);
		System.out.println("Stampa della collezione b: ");
		System.out.println(bHashSet);
		
		// Unione
		System.out.println("Stampa della unione: ");
		System.out.println(union(aHashSet, bHashSet));
		
		// Intersezione
		System.out.println("Stampa della intersezione: ");
		System.out.println(intersection(aHashSet, bHashSet));
		
		// Difference
		System.out.println("Stampa della differenza: ");
		System.out.println(difference(aHashSet, bHashSet));
		
		// Abs
		System.out.println("Stampa della ABS: ");
		System.out.println(abs(union(aHashSet, bHashSet)));
		
	}
	
	// Operazioni di insiemistica
	
	/*
	 * Per eseguire una unione, è conveniente 
	 * adoperare la Set poichè l'implementazione 
	 * TreeSet permette di non mantenere duplicati.
	 */
	public static <T extends Comparable<? super T>> Set<T> union(Set<T> s1, Set<T> s2) {
		Set<T> union = new HashSet<T>();
		union.addAll(s1);
		union.addAll(s2);
		return union;
	}
	
	/*
	 * Per eseguire una intersezione, è conveniente
	 * adoperare la Set allo stesso modo
	 */
	public static <T extends Comparable<? super T>> Set<T> intersection(Set<T> s1, Set<T> s2) {
		Set<T> intersection = new HashSet<T>();
		intersection.addAll(s1);
		intersection.retainAll(s2);
		return intersection;
	}
	
	/*
	 * Per eseguire la differenza, si usa 
	 * la Set
	 */
	public static <T extends Comparable<? super T>> Set<T> difference(Set<T> s1, Set<T> s2) {
		Set<T> difference = new HashSet<T>();
		difference.addAll(s1);
		difference.removeAll(s2);
		return difference;
	}
	
	public static Set<Integer> abs(Set<Integer> s) {
		Set<Integer> abs = new HashSet<Integer>();
		Iterator<Integer> it = s.iterator();
		while (it.hasNext()) abs.add(Math.abs(it.next()));
		return abs;
	}
	
}
