#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, либо вы можете вручную выполнить итерацию по массиву и распечатать его.