Почему Java допускает массивы размера 0?


82

Массивы в java имеют фиксированную длину. Почему тогда Java разрешает массивы размера 0?

String[] strings = new String[0];

Ответы:


122

Это означает, что он пуст. То есть вы можете перебрать его, как если бы он имел элементы и не получил никакого результата:

for(int k = 0; k < strings.length; k++){
   // something
}

Тем самым избегая необходимости проверять. Если бы рассматриваемый массив был null, возникло бы исключение, но в этом случае он просто ничего не делает, что может быть подходящим.


9
Это также полезно для test(Object... objects)явного вызова функции, когда функция естьtest()
Frithjof

51

Почему Java допускает использование массивов размером 1? Разве не бесполезно заключать одно значение в массив? Разве не было бы достаточно, если бы в Java разрешались только массивы размером 2 или больше?

Да, мы можем передать nullвместо пустого массива и один объект или примитив вместо матрицы размера один.

Но есть веские аргументы против такого ограничения. Мои личные главные аргументы:

Ограничение слишком сложно и не обязательно

Чтобы ограничить массивы размерами [1..INTEGER.MAX_INT], нам пришлось бы добавить множество дополнительных проверок, (согласитесь с комментарием Конрадса) логики преобразования и перегрузок методов в наш код. Исключение 0 (и, возможно, 1) из разрешенных размеров массива не экономит затрат, требует дополнительных усилий и отрицательно сказывается на производительности.

Вектор моделей массива

Массив является хорошей моделью данных для вектора (математик, а неVector класс!). И, конечно же, вектор в математике может быть нулевым. Что концептуально отличается от несуществования.


Sidenote - заметной оберткой для массива (char-) является Stringкласс. Неизменяемый Stringматериализует концепцию пустого массива: это пустая строка ( "").


2
Я не верю вашему аргументу о запрете. Java (в отличие, например, от C) уже требует проверки на отрицательные числа. Эта проверка может быть легко адаптирована для размещения 0 (просто измените >= 0на > 0). Но в остальном вы, конечно, правы, поэтому добавление этого ограничения не имело бы смысла.
Конрад Рудольф

На мой взгляд, аргумент итерации цикла кажется лучше: «for (int k = 0; k <strings.length; k ++) {// something}»
dannyxyz22,

2
Нет, на мой взгляд, это не так, потому что в мире без массивов нулевого размера пустые строки (основанные на массивах символов) просто не существовали бы, и поэтому не было бы необходимости рассматривать пустые массивы в циклах. Этот аргумент итерации - очень практичный побочный эффект. В этом мире массив будет иметь как минимум одну запись. (Или два, потому что: зачем нужен массив только для одного элемента?)
Андреас Долк

Проверка на отрицательный индекс и слишком высокий индекс - это одна и та же проверка: отрицательные индексы всегда беззнаковые, не меньше, чем длина массива
Гарольд


16

Подумайте об этом (более подробное объяснение ответа Полдня):

public String[] getStrings() {
 if( foo ) {
  return null;
 } else {
  return new String[] {"bar, "baz"};
 }
}

String[] strings = getStrings();
if (strings != null) {
 for (String s : strings) {
  blah(s);
 }
}

Теперь сравните это с этим:

public String[] getStrings() {
 if( foo ) {
  return new String[0];
 } else {
  return new String[] {"bar, "baz"};
 }
}

// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
 blah(s);
}

Это (возвращение пустых массивов, а не нулевых значений) на самом деле является лучшей практикой в ​​мире проектирования Java API.

Кроме того, в Java вы можете скрывать списки (например, ArrayList) в массивы, и имеет смысл преобразовывать только пустой список в пустой массив.


5

Как и C ++, он позволяет более аккуратно обрабатывать данные при отсутствии данных.


4

Другой случай, когда может быть полезен массив нулевой длины: чтобы вернуть массив, содержащий все элементы в списке:

<T> T[ ] toArray(T[ ] a)

Для передачи типа массива в этот метод можно использовать массив нулевой длины. Например:

ClassA[ ] result = list.toArray(new ClassA[0]);

Массив нулевой длины по-прежнему является экземпляром Object, который содержит нулевые элементы.


2

Я могу придумать один случай, когда пустой массив чрезвычайно полезен, - это использовать его вместо null в ситуации, когда null не допускается. Одним из возможных примеров этого является BlockingQueue массивов. Что бы вы сделали, когда хотите сигнализировать об окончании ввода читающей стороне? Отправка null кажется очевидным выбором, но дело в том, что BlockingQueue не принимает нули. Вы могли бы обернуть свой массив внутри класса с boolean last;полем типа "", но это своего рода излишество. Отправка пустого (нулевого) массива кажется наиболее разумным выбором.


0

Другой случай, когда полезен массив нулевой длины, - это копирование двумерного массива. Я могу написать:

public int[][] copyArray(int[][] array){
     int[][] newArray = new int[array.length][0];
     for(int i=0;i<array.length;i++){
         newArray[i] = array[i];
     }
     return newArray;

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


0

0-длина byte[]или char[]может представлять пустое поле String, отличное от null. Получение байтов или символов, как массивы из строк ( с использованием getBytes(), getChars()из Stringкласса и т.д.) и наоборот формирования Strings из byte[], char[]является довольно распространенным явлением. Например, для нестандартной кодировки, декодирования строк.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.