Не удается получить доступ к последнему элементу массива

Я анализирую файл .CSV, строка за строкой, и я хочу получить значения столбцов. Итак, например, для моего файла .CSV:

time;columnA;columnB,ColumnC
27-08-2013 14:43:00; this is a text; this too; same here

Итак, что я сделал, так это сохранил содержимое в двумерном массиве строк (благодаря split()). Мой массив сделан следующим образом:

array[0][x] = "time".
array[y][x] = "27-08-2013 14:43:00";

это x разных столбцов, но имя каждого столбца хранится только в строке [0][x]. это разные строки, в которых значение хранится как строка.

Моя проблема заключается в следующем: я хочу получить позицию [x] данных, но когда я пытаюсь получить доступ к последнему элементу [x] массива. Я получаю это как сообщение об ошибке

java.lang.ArrayIndexOutOfBoundsException: 17
    at IOControl.ReadCsvFile.getPosVar(ReadCsvFile.java:22)
    at IOControl.ReadCsvFile.<init>(ReadCsvFile.java:121)
    at en.window.Main.main(Main.java:48)

Очевидно, я читаю слишком далеко, но как?

Вот мой код:

//Retrieves the x position of the variable var given as parameter.
private int getPosVar(String[][] index, String var)
{
    int x = 0;
    boolean cond = false;
    while((index[0][x] != null) && (cond != true))
    {
        if (index[0][x].contains(var) == true)
        {
            cond = true;
        }
        x++;
    }
    System.out.println("x = " +x+ "  val = " +index[0][x]);
    return(x);
}

Я подумал, что это может быть потому, что я не проверил, что мое значение x меньше полной строки. как это :

x < index[x].length

Но на самом деле я ничего не менял, и когда я ставлю неизвестное String var, это тоже заходит слишком далеко. Почему?


person trolologuy    schedule 28.08.2013    source источник
comment
У вас есть 4 столбца, но попробуйте получить доступ к 17?   -  person Sotirios Delimanolis    schedule 28.08.2013
comment
Нет, в моем реальном тестовом файле у меня огромное количество данных, для понимания я их вырезал. Но на самом деле у меня 17 столбцов, и я пытаюсь получить доступ к 17-му;)   -  person trolologuy    schedule 28.08.2013
comment
Если у вас 17 столбцов, последний индекс равен 16, так как индексация начинается с 0. Просмотрите свой код с помощью отладчика.   -  person Sotirios Delimanolis    schedule 28.08.2013


Ответы (7)


Проверка правильности индекса перед его использованием также является хорошей идеей:

if ( index == null || index.length == 0 ) return -1;

Ваш цикл while должен выглядеть примерно так:

while ( x < index[0].length )
{
    if ( index[0][x] == null )
    {
        x++;
        continue; // skip possible null entries.
    }

    if ( index[0][x].contains(var) )
    {
        System.out.println("x = " + x + ", val = " + index[0][x]);
        return x; // return the position found.
    }
    x++;
}
return -1;

Использование цикла for (который я предпочитаю):

for ( int x = 0; x < index[0].length; x++ )
{
    if ( index[0][x] == null )
        continue; // skip possible null entries.

    if ( index[0][x].contains(var) )
    {
        System.out.println("x = " + x + ", val = " + index[0][x]);
        return x; // return the position found.
    }
}
person munyul    schedule 28.08.2013
comment
Я не думал, что это может быть так просто :o Странно. Перерыв, безусловно, очень полезно! Большое спасибо ! - person trolologuy; 28.08.2013
comment
@trolologuy, используйте break, если вам нужно оставаться в рамках метода, в противном случае просто используйте return, чтобы вернуть результат, который вам нужен. - person munyul; 28.08.2013

х ‹ индекс[х].длина

Проблема не в длине index[x], а в том, что x слишком велико. Вам необходимо проверить:

index.length < x
person kiheru    schedule 28.08.2013
comment
хм, так что, когда я делаю index[x], я проверяю длину строки в index[x], а когда я проверяю просто x, это не то же самое? - person trolologuy; 28.08.2013
comment
@trolologuy index.length — длина основного массива, index[x].length — длина массива в позиции x. index[x][y].length будет длиной строки в (x, y). - person kiheru; 28.08.2013
comment
Ну, в конце концов, вполне логично ^^ Спасибо большое, я не так понял, теперь понял правильно. - person trolologuy; 29.08.2013

вы должны проверить против

x < index[0].length

и хорошо бы проверить

index != null && index.length > 0

перед доступом к индексу вообще.

После того, как вы нашли правильный результат, ваш код также увеличивает «x++», поэтому x перемещается на один элемент дальше. Если вы сейчас найдете последний элемент или/нет элемента, тогда это приведет к переполнению границ массива, таким образом

System.out.println("x = " +x+ "  val = " +index[0][x]);

выдаст ошибку.

Я бы предложил изменить это так:

private int getPosVar(String[][] index, String var)
{
    int x = 0;
    boolean found = false;

    if(index == null || index.length == 0 || var == null)
        return -1;

    while((x < index[0].length))
    {
        if (index[0][x].contains(var))
        {
            System.out.println("x = " +x+ "  val = " +index[0][x]);
            return(x);
        }
        x++;
    }
    System.out.println("  var = " + var + " not found");
    return -1;
}
person MyChaOS    schedule 28.08.2013

Вы полностью игнорируете границы массива. Где вы убедитесь в цикле while, что ваша переменная x не слишком велика? Нигде.

person Kayaman    schedule 28.08.2013
comment
Я пробовал это: x < index[x].length, но, как дали мне понять другие ответившие, я сделал ошибку, вместо этого я должен был проверить index.length < x. - person trolologuy; 28.08.2013

В конце цикла while вы увеличиваете значение x. После этого вы снова пытаетесь получить значение в методе sysout.

РЕДАКТИРОВАТЬ: Попробуйте поместить x++ в блок else.

person Avsar Himmet    schedule 28.08.2013

Поскольку вы увеличиваете значение после проверки. Что приводит к тому, что следующая проверка становится слишком большой. Вы можете решить эту проблему, просто добавив оператор торможения, подобный этому.

    public static void main(String[] args) {
    String var = "c";
    String[][] index = {{"a","b","c"},{"a","b","c"}};
    int x = 0;
    boolean cond = false;
    while( (index[0][x] != null) && (cond != true) )
    {
        if (index[0][x].contains(var) == true)
        {
            cond = true;
            break;
        }
        x++;
    }
    System.out.println("x = " +x+ "  val = " +index[0][x]);

Кроме того, вы всегда должны пытаться использовать forloop вместо цикла while, они значительно усложняют получение подобных ошибок, если вы проверяете длину массива.

person theodore hogberg    schedule 28.08.2013

Вы можете использовать свою старую программу

открытый класс TwoDStringArray {

static String[][] index = new String[1][3];

public static void main(String[] args) {

    index[0][0] = "amal";
    index[0][1] = "dev";

    int x = 0;
    boolean cond = false;
    String var = "dev";
    while((index[0][x] != null) && (cond != true))
    {

        if (index[0][x++].equals(var) == true)
        {
            cond = true;
            x--;
        }
    }

    System.out.println("x = " +x+ "  val = " +index[0][x] + "    "+ cond);
}

}

O/P ---->>>

x = 1 val = dev true


но вы должны заметить одну вещь, когда объявляете static String[][] index = new String[1][3];

здесь компилятор инициализирует «индекс» с помощью index[0][0]=null , index[0][1]=null , index[0][2]=null

но индекса нет[0][3]

поэтому он покажет ArrayIndexOutOfBoundsException

так что сделайте одну вещь, если в вашей программе есть «n» элементов, а затем объявите «индекс» следующим образом

статическая строка[][] index = новая строка[1][n+1];

person Amal    schedule 28.08.2013