javagenericslinked-listjava-streamsecure-random

Random int stream to generic linked list


In a coding exercise I am working on, I am trying to generate 25 random integers and insert them into a linked list using a function which sorts them. I understand how to do these tasks separately, but I would like to try to do them as a stream. This is the code I wrote to set this up with a sample list to make sure the insertSorted function works.

Node.java

class Node<T extends Comparable<T>> {
    T data;
    Node<T> nextNode;

    Node(T data) {
        this(data, null);
    };

    Node(T data, Node<T> nextNode){
        this.data = data;
        this.nextNode = nextNode;
    };

    void setNext(Node<T> next){
        nextNode = next;
    }

}

SortedList.java

import java.util.NoSuchElementException;

class SortedList<T extends Comparable<T>> {
    private Node<T> firstNode;
    private Node<T> lastNode;
    private String name;

    SortedList(String listName){
        name = listName;
        firstNode = lastNode = null;
    }

    void insertSorted(T item){
        if(isEmpty()){
            lastNode = new Node<T>(item);
            firstNode = lastNode;
        } else if(firstNode.data.compareTo(item) > 0){
            firstNode = new Node<T>(item, firstNode);
        }
        else {
            Node<T> compareNode = firstNode;
            while(compareNode.nextNode != null
            && compareNode.nextNode.data.compareTo(item) < 0){
                compareNode = compareNode.nextNode;
            }
            Node<T> itemNode = new Node<T>(item, compareNode.nextNode);
            compareNode.setNext(itemNode);
        }
    }

    private boolean isEmpty() { return firstNode == null; }

    void print() {
        if (isEmpty()){
            System.out.printf("Empty %s%n", name);
            return;
        }

        System.out.printf("%s is: ", name);
        Node<T> current = firstNode;

        while (current != null){
            System.out.printf("%s ", current.data);
            current = current.nextNode;
        }
        System.out.println();
    }

}

Main.java

class Main{
    public static void main(String[] args){

        // sample example
        SortedList<Integer> sample = new SortedList<>("sample list");
        sample.insertSorted(84);
        sample.insertSorted(65);
        sample.insertSorted(134);
        sample.insertSorted(102);
        sample.insertSorted(954);
        sample.insertSorted(755);

        sample.print();
    }
}

I know that I can generate an array of random ints from a stream with code such as this:

int[] arr = new SecureRandom().ints(25, 0, 100).toArray();

How might I contain a random int stream within the SortedList object above using the insertSorted method?


Solution

  • SortedList::insertSorted(T t) looks like a Consumer<T>, so you can use stream functions that accept a consumer as an argument, like .forEach(...):

    new SecureRandom().ints(25, 0, 100)
        .boxed()
        .forEach( sample::insertSorted );
    

    As @Holger mentions in the comments, .boxed() is not necessary.

    new SecureRandom().ints(25, 0, 100)
        .forEach( sample::insertSorted );
    

    I've verified this on Java8 and Java9, so now I'm not sure when it was ever necessary, or what changed when to make it so.