Запутался в размере массива, указанного в инициализации байтового массива

#java #android #arrays

#java #Android #массивы

Вопрос:

Я не уверен в значении числа при инициализации байтового массива: например byte[] t = new byte[2] .

Я видел в Интернете, что массивы имеют фиксированный размер, поэтому, несмотря ни на что, длина t должна быть 2, верно?

Ну, тогда как в этом примере:

 byte[] t = new byte[0];
t = "hello".getBytes(StandardCharsets.ISO_8859_1);
System.out.println(t.length);
 

результат равен 5? Кажется t , что он просто заполняется всеми элементами, не заботясь о размере.

Мне нужно что-то вроде этого, где я многократно добавляю значения в байтовый массив, не зная, насколько большим окажется массив, могу ли я просто продолжать добавлять что-то вроде t here ?

Комментарии:

1. Знаете ли вы о перезаписи t ?

2. Потому что после переназначения t больше не ссылается на ваш массив. Вместо этого он теперь ссылается на массив, возвращаемый getBytes .

3. ЛОЛ … он сделал и задается вопросом о странном результате

4. Обратите внимание, что в Java все переменные непримитивных типов (включая массивы, даже если тип элемента примитивный) являются ссылками (которые похожи на указатели в C или C , за исключением того, что вы не можете ни к чему, кроме как переназначить их или передать их методам).

5. @Hulk Итак, если бы я использовал System.arraycopy для непрерывного добавления байтов в конец t, как мне следует инициализировать t?

Ответ №1:

В этом примере t бесполезно инициализируется массивом нулевой длины, который выбрасывается, когда t присваивается возвращаемое значение "hello".getBytes(StandardCharsets.ISO_8859_1); .

Это действительно должно быть записано без одноразового значения как

 byte[] t = "hello".getBytes(StandardCharsets.ISO_8859_1);
System.out.println(t.length);
 

Комментарии:

1. Хорошо, и System.arraycopy не заботится о том, как долго t, когда я непрерывно добавляю байты в t?

2. @jklo12334 Я ничего подобного не говорил. Вы читаете javadoc для System.arrayCopy и следуете этим инструкциям. Это не волшебство, все полностью задокументировано, поэтому вам не нужно гадать или спрашивать меня , как все работает. Это, безусловно, имеет значение, насколько велики массивы, поскольку они имеют фиксированный размер, и вы не можете записывать вне массива.

3. @jklo12334 теперь вместо того, чтобы спрашивать о arrayCopy , спросите о своей реальной проблеме. Таким образом, вы можете получить совет по его решению, вместо того, чтобы нам говорить вам, что вы ошибаетесь в своих догадках, и ваша реальная проблема остается нерешенной.

4. @jklo12334 это сайт контроля качества, а не обсуждение. Конечно, вы знаете, как инициализировать массив, вы сделали это в своем вопросе.

5. О, лол, хорошо, позвольте мне перефразировать, извините, что задал вопрос на сайте вопросов и ответов ..? В чем был смысл этого исправления?..? И я не спрашиваю, как инициализировать массив, не могли бы вы процитировать ту часть моего вопроса, где я задаю этот вопрос?

Ответ №2:

если вы попытаетесь напечатать длину t перед ее изменением, вы получите 0, а после перезаписи данных переменной t новая длина равна 5

 byte[] t = new byte[0];
System.out.println(t.length); // result = 0
t = "hello".getBytes(StandardCharsets.ISO_8859_1);
System.out.println(t.length); // result = 5
 

Ответ №3:

Во второй строке вы не заменили содержимое массива, вы заменили сам массив, что означает, что t теперь он указывает на массив длиной 5, состоящий из строки «hello».

Ответ №4:

Основная причина этого при использовании

 t = "hello".getBytes(StandardCharsets.ISO_8859_1);
 

вы создали абсолютно новый массив с новой длиной, поэтому этот код похож

 String t = "hi";
t = "hello";
System.out.println(t.length); // 5
 

Ответ №5:

Массивы в Java имеют фиксированный размер и не могут быть добавлены.
Для этого обычно используется ArrayList , который представляет собой оболочку вокруг массива, которая обрабатывает динамическое изменение размера.

Однако для байтов это не идеально из-за автоматической упаковки, хранение примитивных байтов в списке требует дополнительной памяти и производительности.

Входит ByteArrayOutputStream , также оболочка вокруг массива, которая обрабатывает изменение размера, но на этот раз специально для байтов. Используйте его следующим образом:

 ByteArrayOutputStream stream = new ByteArrayOutputStream();

byte[] hello = "hello ".getBytes(StandardCharsets.ISO_8859_1);
stream.write(hello, 0, hello.length);
byte[] world = "world".getBytes(StandardCharsets.ISO_8859_1);
stream.write(world, 0, world.length);

byte[] combined = stream.toByteArray();
System.out.println(combined.length); // prints 11
 

Примечание: это касается добавления bytes , потому что вопрос был задан. В этом примере может быть проще сначала объединить строки, а затем получить байты за один раз.
Строки могут быть добавлены с помощью StringBuilder or с операторами and = .