/*
 * [TestJoin.java]
 *
 * Summary: Demonstrate how to insert separators between fields, using eight different techniques.
 *
 * 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 2008-06-16
 */
package com.mindprod.example;

import java.util.Arrays;
import java.util.Iterator;

import static java.lang.System.*;

/**
 * Demonstrate how to insert separators between fields, using eight different techniques.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2008-06-16
 * @since 2008-06-16
 */
public final class TestJoin
    {
    /**
     * test empty list
     */
    private static final java.util.List<String> EMPTY = Arrays.asList();

    /**
     * test list
     */
    private static final java.util.List<String> FRUITS = Arrays.asList( "apple", "pineapple", "mango", "cherry" );

    /**
     * test list with empty elements
     */
    private static final java.util.List<String> WITH_EMPTIES = Arrays.asList( "", "pear", "", "peach", "" );

    /**
     * Join items with a separator.
     * Method 1, handles first elt specially,  By Stefan Ram
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join1( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        boolean first = true;
        for ( String item : list )
            {
            if ( first )
                {
                first = false;
                }
            else
                {
                sb.append( separator );
                }
            sb.append( item );
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 2, use explicit Iterator. By Andreas Leitgeb
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join2( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        Iterator<String> it = list.iterator();
        while ( it.hasNext() )
            {
            sb.append( it.next() );
            if ( it.hasNext() )
                {
                sb.append( separator );
                }
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 3, remove final separator. By Roedy Green, also Mark Space.
     * Flaw corrected by Pjotr Kobzda if empty list.
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join3( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        for ( String item : list )
            {
            sb.append( item );
            sb.append( separator );
            }
        // trim off the last separator
        if ( sb.length() > 0 )
            {
            sb.setLength( sb.length() - separator.length() );
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 4, handles last elt specially,  By Eric Sosman
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join4( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        // Separator after every item except the last
        for ( int i = 0; i < list.size(); i++ )
            {
            sb.append( list.get( i ) );
            if ( i + 1 < list.size() )
                {
                sb.append( separator );
                }
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 5, varies the separator  By Eric Sosman
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join5( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        String sep = "";
        for ( String aList : list )
            {
            sb.append( sep );
            sb.append( aList );
            sep = separator;
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 6, handles first elt specially,  By Stefan Ram
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join6( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        if ( list.size() > 0 )
            {
            sb.append( list.get( 0 ) );
            }
        for ( int i = 1; i < list.size(); i++ )
            {
            sb.append( separator );
            sb.append( list.get( i ) );
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 7, non-standard for loop,  By Piotr Kobzda
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    private static String join7( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        if ( list.size() > 0 )
            {
            for ( int i = 0; ; )
                {
                sb.append( list.get( i ) );
                if ( ++i == list.size() )
                    {
                    break;
                    }
                sb.append( separator );
                }
            }
        return sb.toString();
        }

    /**
     * Join items with a separator.
     * Method 8, handled first elt specially,  By Alexander Kasatkin also Daniel Pitts.
     * If you correct the flaw discovered by Piotr Kobzda, this turns into method 1.
     * It gives the wrong result if the first element is empty!!!
     *
     * @param list      items to join together with separators
     * @param separator string to use to separate the elements
     *
     * @return items separated by the separator
     */
    @SuppressWarnings( { "SameParameterValue" } )
    private static String join8( java.util.List<String> list, String separator )
        {
        StringBuilder sb = new StringBuilder( 100 );
        for ( String item : list )
            {
            if ( sb.length() > 0 )
                {
                sb.append( separator );
                }
            sb.append( item );
            }
        return sb.toString();
        }

    /**
     * Test harness
     *
     * @param args command line arguments are ignored.
     */
    public static void main( String args[] )
        {
        out.println( "test FRUITS" );
        out.println( join1( FRUITS, "," ) );
        out.println( join2( FRUITS, "," ) );
        out.println( join3( FRUITS, "," ) );
        out.println( join4( FRUITS, "," ) );
        out.println( join5( FRUITS, "," ) );
        out.println( join6( FRUITS, "," ) );
        out.println( join7( FRUITS, "," ) );
        out.println( join8( FRUITS, "," ) );
        out.println( "test WITH_EMPTIES" );
        out.println( join1( WITH_EMPTIES, "|" ) );
        out.println( join2( WITH_EMPTIES, "|" ) );
        out.println( join3( WITH_EMPTIES, "|" ) );
        out.println( join4( WITH_EMPTIES, "|" ) );
        out.println( join5( WITH_EMPTIES, "|" ) );
        out.println( join6( WITH_EMPTIES, "|" ) );
        out.println( join7( WITH_EMPTIES, "|" ) );
        out.println( join8( WITH_EMPTIES, "|" ) );
        out.println( "test EMPTY" );
        out.println( join1( EMPTY, ":" ) );
        out.println( join2( EMPTY, ":" ) );
        out.println( join3( EMPTY, ":" ) );
        out.println( join4( EMPTY, ":" ) );
        out.println( join5( EMPTY, ":" ) );
        out.println( join6( EMPTY, ":" ) );
        out.println( join7( EMPTY, ":" ) );
        out.println( join8( EMPTY, ":" ) );
        }
    }