1

I'm trying to learn Java Stream API and I'm writing some examples.

So my example is as follows:

I have a list of lists, every list can contain many nodes.

I want a program that checks and returns a node that fulfills some criterion.

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
        public static void main( String[] args ) {
        ArrayList<ArrayList<Node>> lists =  new ArrayList<>();
        /*here i'm creating a list of 10 list from 0 to 9
        * and each list will have one node, the nodes will have a random 
        degree
        */
        IntStream.range(0,10).forEach(  index -> {
                                                lists.add(new ArrayList<>());
                                                int random=new Random().nextInt(10) + 1;
                                                lists.get(index).add(new Node(random));
        });

        Node specificLsit = getaSpecificNode(lists);
    }

   /*we chould retun a new Node(1) if there is a node that have a degree=1
    *and a new Node(2) id there is a node with degree= 2 
    *or null if the above condition fails.
    *so what is the java stream operation to writre for that purpose.
    */
    private static Node getaSpecificNode( ArrayList<ArrayList<Node>> lists ) {
        Node nodeToReturn =null;
        //code go here to return the desired result
        return nodeToReturn;
    }
}

class Node{
    int degree;

    Node(int degree){
        this.degree = degree;
    }
    @Override
    public String toString() {
        return this.degree+"";
    }
}

The 2 for loop is easy to solve the problem, but I want a solution that uses the stream api.

What I have tried :

 private static Node getaSpecificNode( ArrayList<ArrayList<Node>> lists ) {
    Node nodeToReturn =null;
    lists.forEach((list)->{
        list.forEach((node)->{
            if (node.degree ==1 || node.degree ==2 )
                nodeToReturn = node;

        });

    });
    return nodeToReturn ;
}

Unfortunately I'm getting a compilation error that the variable nodeToReturn should be final, but in my case I'm trying to modify it.

Is there any better solution?

4
  • What have you tried? Have you read the stream tutorial? The javadoc of Stream? If not, that's where you should start. Beware: you might learn a lot of stuff. Commented Oct 21, 2018 at 17:54
  • 1
    Read the javadoc of flatMap(), filter() and findAny()/findFirst(). Commented Oct 21, 2018 at 18:00
  • 1
    yes i can understand easily java stream operation,and i have read many tutorials on that, but as a new , choosing the best idea is what i'm looking for. Commented Oct 21, 2018 at 18:00
  • @JBNizet thank you.sure i will review those things.i have already seen them,but as beginner using stream it's not very quick to get the good awnser. Commented Oct 21, 2018 at 18:21

1 Answer 1

2

This should do the trick :

lists.stream().flatMap(List::stream).filter(e -> e.getDegree() == 1 || e.getDegree() == 2)
              .findAny()
              .orElse(null);

Here we convert the ArrayList<ArrayList<Node>> to a flatMap and then apply a filter based on your condition. If a match is found it returns the Node else it returns null.

Sign up to request clarification or add additional context in comments.

5 Comments

hello, thank you for the help, i have an important question about filter. we will filter every node in the list?or we wel filter until we found a good result?
.findAny() will select any Node in the stream. If you want to find the first match then use .findFirst().
may be i didn't explain my question well, so if we have one million node,do we will filter all those million of node and after that we check for our desired node?my question is about efficiency.
because with java 9 we have takeWhile() and dropWhile() that could be better than filter for my question.
If you use .findFirst() then we will stream till we find the first match. So in this case we won't need to stream 1M nodes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.