简体   繁体   中英

Java 8 streams - use original streamed object along the stream action

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?

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));

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM