//CreatingLinkedLists.java
//Illustrates various ways to create a LinkedList.

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

public class CreatingLinkedLists
{
    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 a LinkedList from the above array using
        //the static method Arrays.asList() from the Arrays class:
        LinkedList<Integer> linkedListOfInteger1 =
            new LinkedList<>(Arrays.asList(arrayOfInteger));
        System.out.println("linkedListOfInteger1: " + linkedListOfInteger1);

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

        //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> linkedListOfInteger3 =
            Stream
            .of(arrayOfInteger)
            .collect(Collectors.toCollection(LinkedList::new));
        System.out.println("linkedListOfInteger3: " + linkedListOfInteger3);
        System.out.println(linkedListOfInteger3.getClass().getName());

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

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

        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
    linkedListOfInteger1: [4, 1, 5, 3, 2]
    linkedListOfInteger2: [4, 1, 5, 3, 2]
    linkedListOfInteger3: [4, 1, 5, 3, 2]
    java.util.LinkedList
    linkedListOfInteger4: [4, 1, 5, 3, 2]
    java.util.ImmutableCollections$ListN
    linkedListOfInteger5: [4, 1, 5, 3, 2]

    arrayOfString: klm abc xyz pqr
*/

