• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Creating a Stream<String> reading from System.in?

 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was wondering whether it is possible to create a Stream reading from System.in. Once I had read a few methods in the Stream interface, I thought it looked easy enough.
Stream.generate(new Scanner(System.in)::nextLine).etc();
That seems to work. Is there a neater way to do it? If you try to close the Stream by feeding ctrl‑D or ctrl‑Z (on a Linux box) it seems to produce a NoSuchElementException but that is normal for a Scanner if you close its input. It would appear to be an infinite Stream (or would be if I had an ∞ number of fingers to work the keyboard and produce input).
 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you.
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sadly it doesn't let you transform the input to forms larger than single lines, but at least it's something
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't you have a joining method? Or is that a terminal operation?

Which of the two is better?
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You mean your original code versus mine? I would say that if you want to operate on individual lines, my example conveys the intention more clearly. Your code is more flexible though, as it allows you to tokenize the input in any way you want (consider Scanner::findWithinHorizon). I'm not sure if that's really helpful for keyboard input though.

I don't really like using generate() without a limit() or find...() operation, because generate() and iterate() are supposed to return infinite streams. If I'm honest, I don't like using streams for input in the first place, because lazy evaluation is unreliable if the underlying data source is not referentially transparent. Another problem with generate() is that it produces an unordered stream, which means that if the user enters multiple lines, operations performed on late user input may be executed before operations on early user input.

I feel Streams in Java are like inheritance and operator overloading: Awesome features, but when we first learn about them, we tend to overuse them. My advice is to stick to imperative programming when you have a 'sequential' flow in your application, like handling user input. Streams are awesome for processing *real* collections.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I hadn't noticed the bit about unordered. Agree that a loop with while (myScanner.hasNextXXX())... gets you out of the no such element Exception. Shall try later with the Buffered Reader and lines(). If the Stream fro generate is unordered, you probably won't notice that because all computation done by the Stream will be faster than the keyboard, and you will finish it before the next line of input is available.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The lines() version has the advantage that there is no Exception thrown when the input is closed with ctrl‑D.
 
reply
    Bookmark Topic Watch Topic
  • New Topic