package com.mindprod.example;

import java.util.Arrays;
import java.util.HashSet;

/**
 * Comparing two HashSets. Prepared with IntelliJ
 * <p/>
 * composed with IntelliJ IDEA
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0, 2006-03-30
 */
public final class TestHashSetCompare
    {
// ------------------------------ FIELDS ------------------------------

    /**
     * first set of fruits.
     */
    private static final HashSet<String> fruits = new HashSet<String>( 149
            /* capacity */,
            0.75f
            /* loadfactor */ );

    /**
     * second set of fruits.
     */
    private static final HashSet<String> fruits2 = new HashSet<String>( 149
            /* capacity */,
            0.75f
            /* loadfactor */ );

// -------------------------- STATIC METHODS --------------------------

    /**
     * Look for duplicates in the fruits and fruits2 HashSets using lookup. There is no easy way to modify this method
     * for a case-insensitive compare. You would need to make sure all the elements were the same case when you added
     * them.
     */
    private static void findDupsByLookup()
        {
        // You could look up all fruits in fruits2 or all fruits2 in fruits.
        // We look up all fruits2 in fruits. There are fewer lookups
        // because fruits2 contains fewer elements.
        for ( String fruit : fruits2 )
            {
            if ( fruits.contains( fruit ) )
                {
                System.out.println( "dup found by lookup: " + fruit );
                }
            }
        }

    /**
     * Look for duplicates in the fruits and fruits2 HashSets using retainAll. There is no easy way to modify this
     * method for a case-insensitive compare. You would need to make sure all the elements were the same case when you
     * added them.
     */
    private static void findDupsByRetainAll()
        {
        // make a duplicate of fruits
        HashSet<String> dups = new HashSet<String>( fruits );

        // Throw out everything in fruits unless item has a match in fruits2
        // leaving just the duplicates.
        dups.retainAll( fruits2 );

        for ( String fruit : dups )
            {
            System.out.println( "dup found by retainAll: " + fruit );
            }
        }

    /**
     * look for duplicates in the fruits and fruits2 HashSets using sort. Method could be modified fairly easily to do a
     * case-insensitive sort.
     */
    private static void findDupsBySort()
        {
        String[] fruitsAr = fruits.toArray( new String[fruits.size()] );
        String[] fruits2Ar = fruits2.toArray( new String[fruits2.size()] );
        Arrays.sort( fruitsAr );
        Arrays.sort( fruits2Ar );
        for ( int i = 0, j = 0; i < fruitsAr.length
                                && j < fruits2Ar.length; /* no inc */ )
            {
            int diff = fruitsAr[ i ].compareTo( fruits2Ar[ j ] );
            if ( diff > 0 )
                {
                j++;
                }
            else if ( diff < 0 )
                {
                i++;
                }
            else
            /*  diff == 0 */
                {
                System.out.println( "dup found by sort: " + fruitsAr[ i ] );
                // there can't be dups within each array
                i++;
                j++;
                }
            }// end for
        }

// --------------------------- main() method ---------------------------

    /**
     * Comparing two HashSets. Requires JDK 1.5+.
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        // create a two HashSets each containing a list of fruits

        fruits.add( "apple" );
        fruits.add( "pear" );
        fruits.add( "cherry" );
        fruits.add( "peach" );
        fruits.add( "apricot" );

        fruits2.add( "apricot" );
        fruits2.add( "orange" );
        fruits2.add( "peach" );
        fruits2.add( "mango" );

        findDupsByRetainAll();
        findDupsByLookup();
        findDupsBySort();
        }// end main
    }