Search code examples
javajava-stream

Why can I not count the element(s) of a stream created by Stream.generate?


I am passing a list to create/generate a stream and count the elements of that stream. What I understand is that my empStream contains only one element which is list of Employee. According to Javadocs the stream is closed once it gets consumed/used and we cannot perform other operations on that stream. But here I have not consumed empStream anywhere before empStream.count(); statement.

So why is empStream.count(); not getting executed?

 public class AAAproblem1 {
     public static void main(String[] args) {
         List<Employee> list = new ArrayList<>();
         list.add(new Employee(6, "Nick", 27, "Software Engineer"));
         list.add(new Employee(9, "Tom", 23, "Civil Engineer"));
         list.add(new Employee(3, "Jon", 29, "Mechanical Engineer"));
         list.add(new Employee(4, "Harry", 21, "Surgeon"));
         list.add(new Employee(8, "Don", 25, "Laywer"));
         list.add(new Employee(7, "Marry", 20, "Police"));
         list.add(new Employee(2, "Angel", 22, "Professor"));
         list.add(new Employee(1, "Kate", 23, "Teacher"));
         list.add(new Employee(5, "Evan", 22, "Pilot"));

         generateStream(list);
    }

    private static void generateStream(List<Employee> list) {
        Stream<List<Employee>> empStream = Stream.generate(() -> {
            return list;
        });
       empStream.onClose(()->{System.out.println("empStream is closed");});
       System.out.println("counting number of list inside empStream started");
       // not able to count the elements inside emp stream
       long items = empStream.count();
       System.out.println("counting number of list inside empStream finished");
       System.out.println("The number of employee list in streams is/are - " + items);
       empStream.onClose(()->{System.out.println("empStream is closed");});
    }
 }

Solution

  • Stream.generate returns an infinite sequential unordered stream by calling the supplier. In this case, the stream produced is an infinite stream where each element is the list.

    You cannot apply the count operation to an infinite stream. You need some short-circuiting operation (like limit) to convert the stream generated by the generate method to a finite stream (as shown here)

    list.stream().count() is what you want here.