Java Intstream получить индекс многомерного массива с нулевым значением - PullRequest
3 голосов
/ 26 мая 2020

Java Instream Мне нужен индекс элемента в 2D-массиве с нулевым значением. Я мог бы использовать для одномерного массива, который я сделал ниже, и это сработало:

  IntStream.range(0, myArr.length)
                .filter(x -> myArr[x] == null)
                .findFirst()
                .orElse(-1);

Я мог бы использовать потоки поверх массивов и плоскую карту, чтобы добраться до объекта, но я намерен здесь получить значение i и j, для которого myArr[i][j] равно нулю.

Ответы [ 2 ]

5 голосов
/ 26 мая 2020

Вы можете использовать значение long для передачи двух значений int:

long both = LongStream.range(0, array.length)
    .flatMap(i -> LongStream.range(0, array[(int)i].length).map(j -> j << 32 | i))
    .filter(l -> array[(int)l][(int)(l>>32)] == null)
    .findFirst().orElse(-1);

int j = (int) (both >> 32), i = (int)both;

if(j >= 0) {
    System.out.println("found ("+i+", "+j+")  "+array[i][j]);
}

, но это не проще, чем, например,

int i, j;
search: {
    for(i = 0; i < array.length; i++) {
        var sub = array[i];
        for(j = 0; j < sub.length; j++)
            if(sub[j] == null) break search;
    }
    j = -1;
}

if(j >= 0) {
    System.out.println("found ("+i+", "+j+")  "+array[i][j]);
}
4 голосов
/ 26 мая 2020

Вы можете использовать Stream.iterate и flatMap, чтобы поместить все индексы, для которых значение равно null, в SimpleEntry, где ключ - это первый индекс, а значение - второй индекс:

 Integer[][] integers = {{1, 2, 3, 6}, {4, 5, 6}, {7, 8, null, 11}};
 List<SimpleEntry<Integer, Integer>> collect = 
            Stream.iterate(0, (i) -> i < integers.length, (i) -> ++i)
                .flatMap(i -> IntStream.range(0, integers[i].length)
                      .filter(j -> integers[i][j] == null)
                      .mapToObj(j -> new SimpleEntry<Integer, Integer>(i, j))) 
               .collect(Collectors.toList());

 System.out.println(collect);

Тогда для всех записей в списке collect integers[entry.getKey()][entry.getValue()] == null равно true

РЕДАКТИРОВАТЬ: Проблема сама по себе тривиальна, единственное решение, которое необходимо принять, - какой контейнер следует использовать для хранения индексов. Вот «естественное» решение с Integer массивами:

    List<Integer[]> collect1 = new ArrayList<>();
    for (int i = 0; i < integers.length; i++){
        for (int j = 0; j < integers[i].length; j++){
            if (integers[i][j] == null){
                collect1.add(new Integer[]{i, j});
            }
        }
    }

    collect1.forEach(arr -> System.out.println("null at " +arr[0] + "," + arr[1]));
...