Печать массива сумм, возвращаемых из функции, не выводит суммы

#java #arrays

#java #массивы

Вопрос:

Задача состоит в том, чтобы вернуть сумму каждой строки 2D-массива в одномерный массив.

Пример

 int[][] values = {  
                     {1, 2, 3, 4, 5}, {2, 3, 4, 5, 1}, 
                     {3, 4, 5, 1, 2}, {4, 5, 1, 2, 3}, 
                     {5, 1, 2, 3, 4}
                 };
  

Я хочу напечатать:
Row sums: 15 15 15 15 15

Код

 public int[]allRowSums()
    {
        int rowSum = 0;
        int current = 0;
        int[]a = null;
        for(int i = 0; i < values.length; i  )
        {
            a = new int[values[i].length];
            for(int j = 0; j < values[current].length; j  )
            {
                rowSum = values[current][j];
                a[i]  = rowSum;
            }
            rowSum = 0;
            current  ;            
        }
        return a;        
    }
  

когда я вызываю этот метод, я получаю:
Row sums: [I@15db9742

Комментарии:

1. Попробуйте System.out.println(Arrays.toString(a)); вместо этого

2. Не уверен, что это дубликат, потому что в коде были и другие проблемы. Простая распечатка массива не решила бы проблему.

Ответ №1:

Исправление кода

Текущая реализация возвращает каким-то образом 0, 0, 0, 0, 15 , если напечатана правильно, сначала преобразуя массив в строку:

 System.out.println(Arrays.toString(array));
  

Это происходит потому, что вы всегда обновляете все значения в первом (внешнем) цикле for. Выполните следующие действия

 int rowSum = 0;
int current = 0;
int[] a = new int[values.length];                   // proper initialization to avoid NPE
for (int i=0; i<values.length; i  ) {
                                                    // this line removed
    for (int j=0; j<values[current].length; j  ) {
        rowSum = values[current][j];
        a[i]  = rowSum;
    }
    rowSum = 0;
    current  ;
}
return a;
  

Теперь код работает корректно и будет содержать 15, 15, 15, 15, 15 в вашем примере.

Лучшее решение

Stream API подходит для этого варианта использования. Правильное сочетание сборщика Collectors::summingInt и сопоставления делает свое дело

 int[] array = Arrays.stream(values)
                    .map(i -> Arrays.stream(i)
                                    .boxed()
                                    .collect(Collectors.summingInt(j -> j)))
                    .mapToInt(i -> i)
                    .toArray();
  

Выводим это array в ex. консоль выдаст тот же результат, что и выше.

Ответ №2:

Чтобы повторить результат суммы, вы должны использовать цикл для повторения всех элементов массива.

Попробуйте что-то вроде этого

 for(int intVar :  a)
    System.out.println(intVar);
  

Ответ №3:

Вы возвращаете ссылку на массив, а не на сумму. Также на каждой итерации вы создаете новый массив, из-за чего предыдущие значения теряются.

Просто переместите инициализацию за пределы цикла:

 public static int[] allRowSums() {
    int rowSum = 0;
    int current = 0;
    int[] a = new int[values.length];        // observe this change (only 1 change made)
    for (int i = 0; i < values.length; i  ) {
        for (int j = 0; j < values[current].length; j  ) {
            rowSum = values[current][j];
            a[i]  = rowSum;
        }
        rowSum = 0;
        current  ;
    }
    return a;
}
  

И, как упоминалось в комментариях, вы печатаете ссылку на массив, используйте Arrays.toString() для распечатки массива.

 System.out.println(Arrays.toString(allRowSums()));
  

Комментарии:

1. Это моя точка зрения, как я могу вернуть массив, а не ссылку?

2. Возврат ссылки на массив — это нормально, но когда вы пытаетесь распечатать его, то фактически получаете адрес памяти ссылки. Либо используйте Arrays.toString, либо вы можете вручную выполнить итерацию по массиву и распечатать его.