//CreatingArrayLists.java
//Illustrates various ways to create an ArrayList.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CreatingArrayLists
{
    public static void main(String[] args)
    {
        //First we create an array of integers for use in some of
        //the following examples, and then display its values.
        Integer[] arrayOfInteger =
        {
            4, 1, 5, 3, 2
        };
        System.out.print("arrayOfInteger: ");
        for (int i : arrayOfInteger)
        {
            System.out.print(i + " ");
        }
        System.out.println();

        //1Now we create an ArrayList from the above array using
        //the static method Arrays.asList() from the Arrays class:
        ArrayList<Integer> arrayListOfInteger1 =
            new ArrayList<>(Arrays.asList(arrayOfInteger));
        System.out.println("arrayListOfInteger1: " + arrayListOfInteger1);

        //2Next we create an ArrayList from the above array using
        //the Java 8 Stream "collector" approach:
        ArrayList<Integer> arrayListOfInteger2 =
            Stream
            .of(arrayOfInteger)
            .collect(Collectors.toCollection(ArrayList::new));
        System.out.println("arrayListOfInteger2: " + arrayListOfInteger2);

        //3In this code segment the last line "proves" that if we use an
        //interface as the type rather than the class, we still get the
        //class object we expect.
        List<Integer> arrayListOfInteger3 =
            Stream
            .of(arrayOfInteger)
            .collect(Collectors.toCollection(ArrayList::new));
        System.out.println("arrayListOfInteger3: " + arrayListOfInteger3);
        System.out.println(arrayListOfInteger3.getClass().getName());

        //4With Java 9 we can shorten the above approach to this:
        List<Integer> arrayListOfInteger4 = List.of(4, 1, 5, 3, 2);
        System.out.println("arrayListOfInteger4: " + arrayListOfInteger4);
        System.out.println(arrayListOfInteger4.getClass().getName());
        //But note that we get a somewhat different class ...

        //5We can now also intialize an ArrayList directly with a code block:
        ArrayList<Integer> arrayListOfInteger5 = new ArrayList<Integer>()
        {
            {
                add(4);
                add(1);
                add(5);
                add(3);
                add(2);
            }
        };
        System.out.println("arrayListOfInteger5: " + arrayListOfInteger5);

        System.out.println();

        //========================================================
        //Exercise:
        //Repeat what we did in the above five code segments, but
        //with strings instead of integers, and here is a starting
        //array of strings to use:
        String arrayOfString[] =
        {
            "klm", "abc", "xyz", "pqr"
        };
        System.out.print("arrayOfString: ");
        for (String s : arrayOfString)
        {
            System.out.print(s + " ");
        }
        System.out.println();
    }
}
/*  Output:
    arrayOfInteger: 4 1 5 3 2
    arrayListOfInteger1: [4, 1, 5, 3, 2]
    arrayListOfInteger2: [4, 1, 5, 3, 2]
    arrayListOfInteger3: [4, 1, 5, 3, 2]
    java.util.ArrayList
    arrayListOfInteger4: [4, 1, 5, 3, 2]
    java.util.ImmutableCollections$ListN
    arrayListOfInteger5: [4, 1, 5, 3, 2]

    arrayOfString: klm abc xyz pqr
*/
