38

I'm learning about Streams in Java 8. I got confused about this concept:

A collection is an in-memory data structure, which holds all the values that the data structure currently has—every element in the collection has to be computed before it can be added to the collection. In contrast, a stream is a conceptually fixed data structure in which elements are computed on demand.

I don't understand, how can a Collection only hold values that must have been computed before they can be added to the collection? And also, what is meant by the comparison of a Stream with a fixed data structure?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Tea
  • 873
  • 2
  • 7
  • 25
  • 2
    Unclear what you're asking. What don't you understand about 'computed before it can be added'? or 'conceptually fixed data structure'? It's also unclear whether you're asking about the meanings of these terms, as per your question, or the difference between colelctions and streams, as per your title, which is even more trivial. – user207421 Sep 11 '16 at 04:00
  • The purpose of both are different. Fundamentally, the objective of a collection is to manage its elements like add, remove, add at particular index etc... And, the objective of a stream is to process such elements like find any element matching a condition, filter elements basing on a condition etc... – lupchiazoem Oct 28 '18 at 13:01
  • The quote is from *[Java 8 in Action](https://www.manning.com/books/java-8-in-action)* "4.3. Streams vs. collections". – Jason Law Jan 28 '20 at 14:01

2 Answers2

69

You didn't provide the source of your quote, so let me quote the javadoc to you:

Streams differ from collections in several ways:

  • No storage. A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.
  • Functional in nature. An operation on a stream produces a result, but does not modify its source. For example, filtering a Stream obtained from a collection produces a new Stream without the filtered elements, rather than removing elements from the source collection.
  • Laziness-seeking. Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Intermediate operations are always lazy.
  • Possibly unbounded. While collections have a finite size, streams need not. Short-circuiting operations such as limit(n) or findFirst() can allow computations on infinite streams to complete in finite time.
  • Consumable. The elements of a stream are only visited once during the life of a stream. Like an Iterator, a new stream must be generated to revisit the same elements of the source.

In contrast, a Collection is a container of objects (elements). You can't get (retrieve) an object from a collection unless the object was previously added to the collection.

Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • `You can't get (retrieve) an object from a collection unless the object was previously added to the collection.` This is not true, there is no such contract. A collection can start its life non-empty; it can also be lazy and realize an element only when you ask for it (e.g., Hibernate's lazy collections). Even finite size is a questionable property since the iterator can return an unbounded number of elements. – Marko Topolnik Sep 11 '16 at 06:00
  • 5
    @MarkoTopolnik An `Iterator` is not a `Collection`, so please don't confuse the two. Collections have a `size()`. --- I consider giving a list of elements during construction to be the same as adding them at that time. The elements exist before becoming a member of the collection, which is the point. --- But you are right, it *is* possible to implement the `Collection` interface without having actual storage backing it, Hibernate being an example. But even there, it's a technically of lazy loading from the *actual* store (the database). The elements already exist. – Andreas Sep 11 '16 at 06:18
  • Collection's contract mandates an iterator so i'm not confusing anything. Collections do have a `size()`, which is why i said it was "questionable"---for example, `Map` has size as well, yet you can have more than 2^31 elements in a `HashMap`. The characterization of elements as "actually existing" is philosophical. The may also be computed at the time of realization, for example by throwing a die. – Marko Topolnik Sep 11 '16 at 06:34
  • 3
    @Marko Topolnik: The Collection API has been retrofitted to allow more than 2³¹ elements, in which case the collection has to return `Integer.MAX_VALUE` from `size()`, however the current implementation of `HashMap` has an `int` size field that will silently overflow, so it doesn’t adhere to this convention and Streams created from such a map would fail to report the correct `long` size, so I’d not consider it a supported use case, but just a missing error detection. – Holger Sep 12 '16 at 10:45
  • @holger Yes, both `Collection` and `Map` specify this `Integer.MAX_VALUE` logic. As Java heaps grow, the noncompliance of `HashMap` will become a more pressing issue. – Marko Topolnik Sep 12 '16 at 10:59
4

Some basic differences are

Difference between Collection and Stream

But these are some finite differences , you have to explore to know more. Collections are like CD/DVD and stream's are the movies. Streams can be stateless and statefull.

subhashis
  • 4,629
  • 8
  • 37
  • 52