2013-04-03 4 views
0

У меня следующая ситуация:Массивы Java: как обеспечить семантическую правильность используемых индексов?

final int I = 10; 
final int MU = 100; 
final int P = 100; 

int[][] a = new int[I][MU]; 
int[][] b = new int[I][P]; 

for(int i = 0; i < I; i++) { 
    for(int mu = 0; mu < MU; mu++) { 
    for(int p = 0; p < P; p++) { 
     a[i][mu] = ... // something 
     b[i][p] = ... // something 
    } 
    } 
} 

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

a[mu][i] = ... 

В принципе, я могу поймать эту ошибку. Однако, следующая ошибка намного сложнее поймать:

b[i][mu] = ... 

Здесь не будет исключением времени выполнения, поскольку mu имеет тот же диапазон p. Однако эти ошибки вызывают семантические проблемы в коде.

Наконец, мой вопрос: что это лучший способ, чтобы запрограммировать эти массивы таким образом, что массив a может быть доступен только с правильными индексами (i и mu в данном случае)?

Спасибо!

+0

1) Не поймать 'ArrayIndexOutOfBoundsException'. 2) Лучший способ - тщательно писать и тестировать свой код. –

+0

Во-первых, нет смысла иметь две отдельные конечные переменные (константы) с одинаковым значением. Также, чтобы ответить на вопрос, вам нужно объяснить, для чего вам нужно тройное вложение. Для меня имеет смысл иметь 2 двойных вложенных цикла (по одному для каждого 2D-массива), затем тройное вложение. – prashant

+0

prashant, вы правы относительно гнездования, но это проблема с моим примером, возможно, я должен был уменьшить его до наименьшего возможного примера и вообще не показывать петли! Это связано с тем, что ситуация, о которой я думаю, в сущности - это когда вам нужно индексы, которые могут использоваться для доступа к различным массивам, но могут ошибочно использоваться в неправильном массиве. – gdiazc

ответ

2

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

Мы не можем сказать, что ваш тип предназначен для представления (подсказка: использовать более осмысленные имена), но если у вас есть класс:

class Foo { 
    private final int[] a = new int[MU]; 
    private final int[] b = new int[P]; 

    ... 
} 

Тогда вы могли бы:

Foo[] foos = new Foo[I]; 

В этот момент очень ясно, как структурируются массивы - вы вряд ли поступите неправильно, потому что у вас будет такой петля, как:

for (int i = 0; i < foos.length; i++) { 
    Foo foo = foo[i]; 
    // Use foo 
} 

Я также призываю вас использовать улучшенный цикл:

for (Foo foo : foos) { 
    ... 
} 
+0

Спасибо, Джон, я согласен с вашим решением, хотя это повлияет на производительность? Я был в ситуации, когда виртуальная машина Java потратила большую часть времени на создание объектов (в этом случае мы будем создавать объект 'Foo' для каждого' i'). – gdiazc

+0

Другой вопрос: скажем, я использую новый синтаксис 'for' (' for (Foo foo: foos) ') и в какой-то момент внутри' for' мне нужен индекс 'i'' foo'. Есть простой способ сделать это?(Я бы не хотел делать 'int i = 0; for (Foo foo: foos) {/ * использовать i */i ++;}' – gdiazc

+0

@Gonzalo: Нет, если вам нужен индекс, вы должны использовать регулярный цикл. –

 Смежные вопросы

  • Нет связанных вопросов^_^