0

I have an Iterator of Iterator, from which I want to generate a 2D array. I have the following code:

StreamSupport.stream(Spliterators.spliteratorUnknownSize(rowIterator, Spliterator.ORDERED), false)
        .map((Row row) -> {
            Iterator<Cell> cellIterator = row.cellIterator();
            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(cellIterator, Spliterator.ORDERED), false)
                    .map(Utils::genericCellMapper)
                    .toArray();
        })
        .toArray(Object[][]::new);

But Eclipse editor is giving compilation error: Cannot infer type argument(s) for <R> map(Function<? super T,? extends R>).

If I change the above code as:

StreamSupport.stream(Spliterators.spliteratorUnknownSize(rowIterator, Spliterator.ORDERED), false)
        .map(new Function<Row, Object[]>() {

            @Override
            public Object[] apply(Row row) {
                Iterator<Cell> cellIterator = row.cellIterator();
                List<Object> list = StreamSupport.stream(Spliterators.spliteratorUnknownSize(cellIterator, Spliterator.ORDERED), false)
                        .map(Utils::genericCellMapper)
                        .collect(Collectors.<Object>toList());

                return list.toArray(new Object[list.size()]);
            }
        })
        .toArray(Object[][]::new);

It works. What I understand that in the first variant compiler is unable to determine the return type of the mapper. Do I need to use the second variant to achieve the requirement or it is a problem with Eclipse?


Similar question from other SO threads

Lino
  • 19,604
  • 6
  • 47
  • 65
Tapas Bose
  • 28,796
  • 74
  • 215
  • 331
  • did u try `javac` by any chance? – Eugene Apr 25 '18 at 13:23
  • @Eugene, no I didn't. – Tapas Bose Apr 25 '18 at 13:24
  • plz do, could be an `ECJ` issue – Eugene Apr 25 '18 at 13:25
  • 1
    You should provide the declaration of `rowIterator`. If it is a raw type, the behavior is not surprising. Besides that, you’re doing unnecessary work. There is no sense in collecting into a `List`, just to call `toArray` on it. Use `toArray()` directly on the stream. Further, all `Iterable`s inherit a `default spliterator()` method. So you should be able to use `StreamSupport.stream(row.spliterator(), false).map(Utils::genericCellMapper).toArray()`; I suppose, you could do similar for the outer stream, but you didn’t provide enough context. – Holger Apr 26 '18 at 09:01
  • So, assuming that your input is an implementation of `org.apache.poi.ss.usermodel.Sheet`, you could simply do `Object[][] array = StreamSupport.stream(sheet.spliterator(), false) .map(row -> StreamSupport.stream(row.spliterator(), false).map(Utils::genericCellMapper).toArray()) .toArray(Object[][]::new);`… – Holger Apr 26 '18 at 09:06

0 Answers0