Josh Grinberg
Josh Grinberg

Reputation: 523

Are Java 8 streams immutable?

If my API provides a stream, is there a way for clients to modify the underlying collection?

For example:

class ListWrapper {
  List<String> myList;
  ...
  Stream<String> getStream() {
    return myList.stream();
  }
}

Is it possible for a client to call listWrapper.getStream() and somehow modify the contents of myList?

Upvotes: 3

Views: 7952

Answers (1)

knittl
knittl

Reputation: 265648

A stream cannot modify the underlying collection (if the collection itself is not exposed), so elements cannot be added or removed, nor can the order be changed. When you consume a stream in a terminal operation, a new collection is built (but you can collect into another existing collection).

However, what is still possible is for stream operations to modify single elements if the elements themselves are mutable. This is bad practice, but it can be done.

Example:

class Item { public int x; public Item(int x) { this.x = x; } }
var list = List.of(new Item(1), new Item(2));
list.stream().peek(item -> item.x = 3).collect(toList());

When the stream is consumed with collect (or count or forEach or any other terminal operation), the peek callback will modify each element. After running above code, your list will contain 2 items with a value of x=3. peek is an arbitrarily chosen non-terminal operation. The same behavior can be observed with filter, map/flatMap, or any other non-terminal operation.

In spirit this is very similar to: Is Java "pass-by-reference" or "pass-by-value"?, but minimally better hidden.

Upvotes: 9

Related Questions