Monika Shiralkar wrote:1) Streams are used to allow Java to do functional programming. For e.g convert list go stream and then apply filter.
Well, I would say that streams are the place, in the libraries, where they put all the functional methods for processing groups of data, like collections.
Monika Shiralkar wrote:2) Streams is data executed in sequence
That's the most basic definition, I think. A sequence of data, combined with a rich API of methods to help you do the processing.
Monika Shiralkar wrote:3) Streams cannot be operated upon more than once .
This was an intentional design choice to encourage users to structure their processing in a way that does not require all the data to be held in memory at once. Without streams, people typically use Lists and other collections for everything. And that's usually fine... you loop through a list, then you loop through it again to do something else, and maybe once more for something else. In order to do that, the list keeps references to everything in the list, to prevent it from being garbage collected. But, some data is too big to comfortably fit it all in memory at once. Or even if you
can, it uses more memory than you really need to. It's often much more efficient to structure your processing to do everything in one loop, if possible. So Stream does that, empowering you to do all sorts of things concisely and efficiently... but all in one loop.
When I say loop here, you don't
see the one loop as a loop, in your code. But it's there, behind the scenes. If you pay attention to the idea of a
terminal operation on a stream... whenever you invoke a terminal operation on a stream, you call code that executes the loop. All the operations you've defined so far in lambdas and method references... those will finally be called, all behind the one big loop, once you've invoked a terminal operation. Once you do that, there's no more Stream for you to operate on. You're done looping.
Another way to think of this is, a Stream is basically a modern, enhanced version of an Iterator. Not an Iterable, which can be looped through repeatedly by calling iterator() multiple times... but a single simple Iterator, which lets you see everything in the sequence, just once. A Stream is like that... but it has a bunch of other methods added, to make your processing more concise and efficient.
Note that in many cases, if you really
need to, you can process everything more than once, by making sure there's a List or other Collection being used to save everything in memory. Either you start with one, or you save your intermediate results midway through your processing using Collectors.asList() or something similar. That's always possible. But you have to choose to do that, rather than be forced to do that. Streams encourage you to do everything in one loop, and if you can't, then save your results to a List, and loop as many more times as needed.