Как Вы инициализируете 2 размерных массива, когда Вы не знаете размера

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
8
задан Keith Sirmons 8 September 2008 в 21:06
поделиться

6 ответов

Вы не можете использовать массив. Или скорее необходимо было бы выбрать размер, и если бы Вы закончили тем, что нуждались больше затем, то необходимо было бы выделить новый, больший, массив, скопировать данные из старого в новый и продвинуться как прежде (пока Вы не превышаете размер нового...),

Обычно Вы пошли бы с одним из классов набора - ArrayList, Списка <>, LinkedList <>, и т.д. - какой во многом зависит от того, что Вы ищете; Список даст Вам самую близкую вещь тому, что я описал первоначально, в то время как LinkedList <> избежит проблемы частых перераспределений (за счет более медленного доступа и большего использования памяти).

Пример:

List<float[]> _calibrationSet = new List<float[]>();

// ...

while (recordsToRead)
{
    float[] record = new float[SensorCount];
    for (int i = 0; i < SensorCount; i++)
    {
        record[i] = calibrationArrayView.ReadFloat();
    }
    _calibrationSet.Add(record);
}

// access later: _calibrationSet[record][sensor]

О, и это стоит отметить (как Grauenwolf сделал), что то, что я делаю здесь, не дает Вам ту же структуру памяти, как единственный, многомерный массив был бы - под капотом, это - массив ссылок на другие массивы, которые на самом деле содержат данные. Это ускоряет создание массива очень путем создания перераспределения более дешевым, но может оказать влияние на скорость доступа (и, конечно, использование памяти). Является ли это проблемой для Вас, во многом зависит от того, что Вы будете делать с данными после того, как они загрузились... и существует ли двести записей или два миллиона записей.

8
ответ дан 5 December 2019 в 15:28
поделиться

Вы не можете создать массив в.NET (в противоположность объявлению ссылки на него, которая является тем, что Вы сделали в своем примере), не указывая его размеры, или явно, или неявно путем определения ряда литеральных значений при инициализации его. (например, интервал [] array4 = {{1, 2}, {3, 4}, {5, 6}, {7, 8}} ;)

Необходимо использовать структуру данных переменного размера сначала (универсальный список массивов 1-d с 22 элементами был бы самым простым), и затем выделите массив и скопируйте данные в него после того, как чтение закончено, и Вы знаете, в каком количестве строк Вы нуждаетесь.

2
ответ дан 5 December 2019 в 15:28
поделиться

Я просто использовал бы список, затем преобразовал бы тот список в массив.

Вы заметите здесь, что я использовал зубчатый массив (плавание [] []) вместо квадратной антенной решетки (плавание []). Помимо того, чтобы быть "стандартным" способом сделать вещи, это должно быть намного быстрее. При преобразовании данных от списка до массива только необходимо скопировать [calibrationRow] указатели. Используя квадратную антенную решетку, необходимо было бы скопировать плавания [calibrationRow] x [SensorCount].

        var tempCalibrationSet = new List<float[]>();
        const int SensorCount = 22;
        int calibrationRow = 0;

        while (recordsToRead())
        {
            tempCalibrationSet[calibrationRow] = new float[SensorCount];

            for (int i = 0; i < SensorCount; i++)
            {
                tempCalibrationSet[calibrationRow][i] = calibrationArrayView.ReadFloat();
            } calibrationRow++;
        }

        float[][] _calibrationSet = tempCalibrationSet.ToArray();
1
ответ дан 5 December 2019 в 15:28
поделиться

Я обычно использую более хорошие наборы для этого вида работы (Список, ArrayList и т.д.) и затем (если действительно необходимый) бросал к T [] когда я сделан.

0
ответ дан 5 December 2019 в 15:28
поделиться

необходимо было бы или предварительно выделить массив Максимальному размеру (плавание [999,22]) или использовать другую структуру данных.

я предполагаю, что Вы могли копировать/изменять размер на лету.. (но я не думаю, что Вы хотели бы к),

я думаю, что Список звучит разумным.

0
ответ дан 5 December 2019 в 15:28
поделиться

Вы могли также использовать двумерный ArrayList (от Системы. Наборы) - Вы создаете ArrayList, затем помещаете другой ArrayList в нем. Это даст Вам динамическое изменение размеров, Вам нужно, но за счет немного служебного.

0
ответ дан 5 December 2019 в 15:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: