• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Can you add to a stream? Otherwise, of what use is an empty stream...

 
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you add to a stream? Otherwise, of what use is an empty stream...


 
Master Rancher
Posts: 5060
81
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In general, you can't add to a stream once it's been created.  You can use a Stream.Builder (or DoubleStream.Builder, etc) and add to that... but once you call build() and get a Stream (or DoubleStream, etc) you can't add to it.  (Much like the relationship between String and StringBuilder.)  Alternately, if you get a Stream from some other source, you may be able to add to it by adding to the source, before you call a terminal operation.  E.g.:

But that's of limited use, and not generally a reliable way to accomplish anything.  It's much clearer to call stream() only after you're done modifying the list.  Note also that there are many ways to create lists and streams that are not mutable in any way.
 
As for "what use is an empty Stream", though... well, you can use it anytime you have an API that expects a Stream, but you don't have anything to pass it.  Much like you might need to use an empty list or zero-length array.  For example, the Optional class has a method to convert the optional to a Stream of zero or one elements.  This is done with:

Another use case is for unit testing.  If you have code that operates on a Stream and you want to test it, it's probably a good idea to include an empty stream as one of your test cases.

In general, if you come across a need for an empty stream, it will be obvious.  Until then, it doesn't really matter much... you can just trust that some people have found it useful, and methods exist to create empty streams.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:In general, you can't add to a stream once it's been created.  ...
 



Thank you for a thorough answer. I will digest it.
 
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:. . . of what use is an empty stream... . . .

You can start off with a “populated” Stream and methods like filter() and limit() can remove all elements. For example, in the following example, everything is coloured white, black, green or blue. So line 3 produces an empty Stream.The takeWhile() and dropWhile() methods can also produce an empty Stream. In the following example, you should be able to work out that I have made a mistake, and I challenge you to correct it.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:In the following example, you should be able to work out that I have made a mistake
            .dropWhile(i -> i != 0)
            .takeWhile(i -> i != 0) // Work out how to avoid repeated code


only zeroes will pass through the dropwhile but takewhile will reject them all.
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you are confusing takeWhile() or dropWhile() and filter(); please suggest how you would correct my mistake.
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please don't edit posts like that; people will think I am ignoring the collect() call. That collect() call is how you can collect a Stream into a particular kind of List, in this case the well‑known ArrayList. Well, one way to do it.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I think you are confusing takeWhile() or dropWhile() and filter(); please suggest how you would correct my mistake.



I don't know what you are trying to do. You will always get an empty list at the end.



OUTPUT:

1
2
3
4
5
[]



 
Mike Simmons
Master Rancher
Posts: 5060
81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:I don't know what you are trying to do. You will always get an empty list at the end.


I found this confusing too, but the key explanation was in the comment:

This describes what the intent was, which is not an empty stream - unless you enter two 0's in a row.  So for this input:

the goal is to ignore everything before (and including) the first 0, and also everything after (and including) the second 0.  What remains is:

However, the code he wrote does produce an empty stream.  He's asking, how could it be changed to produce the input described in the comment?

I'm not sure how this is an example of why we might need an empty stream.  Rather, it's an example of how a programming error might produce one unintentionally.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:
I found this confusing too, but the key explanation was in the comment:

This describes what the intent was, which is not an empty stream - unless you enter two 0's in a row.  So for this input:

the goal is to ignore everything before (and including) the first 0, and also everything after (and including) the second 0.  What remains is:

However, the code he wrote does produce an empty stream.  He's asking, how could it be changed to produce the input described in the comment?

I'm not sure how this is an example of why we might need an empty stream.  Rather, it's an example of how a programming error might produce one unintentionally.



The way you explained it makes sense.



OUTPUT

[2, 3, 4]
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My earlier code showed how an empty Stream can arise from the correct operation of correctly‑code.

Mike Simmons wrote:. . . I'm not sure how this is an example of why we might need an empty stream.  Rather, it's an example of how a programming error might produce one unintentionally.

Yes, I did say there was an error in my code and I think MS has found it. I don't, however, think AP has fully identified my error. Let's expand the code a bit to use System.in on JShell.

=Campbell's JShelljshell> {
  ...>     Scanner scan = new Scanner(System.in);
  ...>     List<Integer> numbers =
  ...>         scan.tokens()  // all tokens
  ...>             .filter(s -> new Scanner(s).hasNextInt()) // keep only ints
  ...>             .mapToInt(Integer::parseInt) // change to primitive
  ...>             .dropWhile(i -> i != 0) // miss out non-zeroes
  ...>             .takeWhile(i -> i != 0) // go on until zero is found
  ...>             .mapToObj(Integer::valueOf) // Turn into object
  ...>             .collect(ArrayList::new, List::add, List::addAll);
  ...>     System.out.println(numbers);
  ...> }
Campbell 123 is 876 brilliant 999 and 0 CodeRanch 123 is 234 a 345 good 456 place 0 to -987654321 learn.

Intended result = [123, 234, 345, 456] and result obtained = []. Did your peek() call give you any useful information?
The change to ints and back can be replaced by one change, to Integers.
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is a much simpler way to remedy the error. It is only necessary to “lose” the one zero, which you can do with .skip(1L).
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The error is that after the 0 is found, the Stream has a 0 as its first element, which the takeWhile() call will interpret as the end of the Stream.
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:Can you add to a stream? . . .

It is possible to concatenate two Streams of compatible types. Method link. Not sure, but I don't think  that feature is used at all frequently.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:There is a much simpler way to remedy the error. It is only necessary to “lose” the one zero, which you can do with .skip(1L).


What if it is not "one zero" but "...00...." Will skip(1) still work?
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you have two consecutive 0s, you are signalling that you want an empty Stream; skip(1L) will interpret that correctly.
 
Marshal
Posts: 8960
646
Mac OS X Spring VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:what use is an empty stream


It's been provided already an actual use within Optional class.

Here is another, just fictional example use which I pulled from a thin air (may help other potential readers to visualise it better):

You could use Stream.of() as well though, Stream.empty() semantically it just makes more sense if you know you want empty.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:My earlier code showed how an empty Stream can arise from the correct operation of correctl



The original question is not answered. Not about returning an empty stream as an end condition in a check, but why would one create it as in the call empty() in the OP.
 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:



This case makes sense.
 
Sheriff
Posts: 4641
582
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:The original question is not answered. Not about returning an empty stream as an end condition in a check, but why would one create it as in the call empty() in the OP.



I feel that this post provided a good explanation:

Mike Simmons wrote:As for "what use is an empty Stream", though... well, you can use it anytime you have an API that expects a Stream, but you don't have anything to pass it.  Much like you might need to use an empty list or zero-length array.  For example, the Optional class has a method to convert the optional to a Stream of zero or one elements ...

 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron McLeod wrote:
I feel that this post provided a good explanation:

Mike Simmons wrote:As for "what use is an empty Stream", though... well, you can use it anytime you have an API that expects a Stream, but you don't have anything to pass it.  Much like you might need to use an empty list or zero-length array.  For example, the Optional class has a method to convert the optional to a Stream of zero or one elements ...



I agree. Thanks.
 
Campbell Ritchie
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Anil Philip wrote:. . .  The original question is not answered. . . .

Yes, Mike and [edit]Ron[/edit] have both answered it. Occasionally you will use it to signal that there are zero values. For example, I have a name in two parts, so the most accurate ways to represent my middle names would be a 0‑length array, or a 0‑size List, or a 0‑element Stream. Call the Stream 0‑element rather than empty and you are being assertive about my having zero middle names. And don't try using null instead.
 
He was expelled for perverse baking experiments. This tiny ad is a model student:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic