/*
 * [TestHashSetCompare.java]
 *
 * Summary: Comparing two HashSets. Prepared with IntelliJ.
 *
 * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2006-03-30
 */
package com.mindprod.example;

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

import static java.lang.System.*;

/**
 * Comparing two HashSets. Prepared with IntelliJ.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2006-03-30
 * @since 2006-03-30
 */
public final class TestHashSetCompare
    {
    /**
     * first set of fruits.
     */
    private static final HashSet<String> fruits = new HashSet<>( 149
            /* capacity */,
            0.75f
            /* loadfactor */ );

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

    /**
     * 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 ) )
                {
                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<>( fruits );
        // Throw out everything in fruits unless item has a match in fruits2
        // leaving just the duplicates.
        dups.retainAll( fruits2 );
        for ( String fruit : dups )
            {
            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 */
                {
                out.println( "dup found by sort: " + fruitsAr[ i ] );
                // there can't be dups within each array
                i++;
                j++;
                }
            } // end for
        }

    /**
     * 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
    }