Reputation: 18541
I am running Stream
operations on an array of Integer
s.
I then create a Cell
object that does some manipulations and apply a filter,
and I want to create a map of Integer
to Cell
with only the valid Cell
s.
Something along this line:
List<Integer> type = new ArrayList<>();
Map<Integer, Cell> map =
list.stream()
.map(x -> new Cell(x+1, x+2)) // Some kind of Manipulations
.filter(cell->isNewCellValid(cell)) // filter some
.collect(Collectors.toMap(....));
Is it possible to use original streamed object along the stream action?
Upvotes: 4
Views: 732
Reputation: 49646
Is it possible to use original streamed object along the stream action?
Yes, until you don't use a map
operation.
You need a Function<Cell, Integer>
to restore an original value. In your example, it is (Cell cell) -> cell.getFirst() - 1
:
.collect(Collectors.toMap(cell -> cell.getFirst() - 1, Function.identity()));
I suggest writing Function<Integer, Cell>
and Function<Cell, Integer>
functions and not building unnecessary wrapper classes for a single stream process:
final Function<Integer, Cell> xToCell = x -> new Cell(x + 1, x + 2);
final Function<Cell, Integer> cellToX = cell -> cell.getX1() - 1;
final Map<Integer, Cell> map =
list
.stream()
.map(xToCell)
.filter(cell -> isNewCellValid(cell))
.collect(Collectors.toMap(cellToX, Function.identity()));
Of course, it's efficient for the operations that can be simply or intuitively inverted.
Upvotes: 1
Reputation: 393986
You can store the original Stream
element if your map
operation creates some instance that contains it.
For example:
Map<Integer, Cell> map =
list.stream()
.map(x -> new SomeContainerClass(x,new Cell(x+1, x+2)))
.filter(container->isNewCellValid(container.getCell()))
.collect(Collectors.toMap(c->c.getIndex(),c->c.getCell()));
There are some existing classes you can use instead of creating your own SomeContainerClass
, such as AbstractMap.SimpleEntry
:
Map<Integer, Cell> map =
list.stream()
.map(x -> new AbstractMap.SimpleEntry<Integer,Cell>(x,new Cell(x+1, x+2)))
.filter(e->isNewCellValid(e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
Upvotes: 6