İçinde kodlanmış bir dizenin uzunluğu nedir? Yukarıdaki kod satırı neden yazdırıyor 12, bunun yerine 11 yazdırılmalı mı?Bir ByteBuffer
cevap
dizinin uzunluğu ByteBuffer
boyutudur ' kodlama yaptığınız karakter sayısına eşittir, ancak bunlardan eşit değildir. Eğer encode()
yöntem haline inerseniz
, sen CharsetEncoder#encode(CharBuffer)
şuna benzer olduğunu göreceksiniz ... en bir ByteBuffer
için bellek ayrılamadı nasıl bir göz atalım: my ayıklayıcıya göre
public final ByteBuffer encode(CharBuffer in)
throws CharacterCodingException
{
int n = (int)(in.remaining() * averageBytesPerChar());
ByteBuffer out = ByteBuffer.allocate(n);
...
, UTF_8$Encoder
'un averageBytesPerChar
değeri 1.1
ve String
girdisi 11
karakterleri içerir. 11 * 1.1 = 12.1
ve kod hesaplama yapar bir int
için toplam atan, yani ByteBuffer
Sonuçta ortaya çıkan bu üzerinden ağ dikkatli bir şekilde ilk olmadan ByteBuffer.array yöntemi kullanma için şüpheli 12.
Vay canına, bu ortağa kimin çıkacağını ve hangi veri kümesini kullandıklarını merak ediyorum.Her nasılsa, kafasını fırında ve ayaklarını dondurucuda tutan istatistikçiyle ilgili şakayı hatırlatıyor ve kendini ortalama olarak rahat bir şekilde sıcak olarak ilan ediyor. –
ByteBuffer
döndürür. Bu, arabelleğin kapasite (gerçekten olası dilimlemeden dolayı bile değil), kaç bayt kullanıldığını değil. malloc(10)
'un 32 bayt belleğe geri dönüşü ücretsizdir.
System.out.println(Charset.forName("UTF-8").encode("hello world").limit());
Bu 11 (beklendiği gibi).
Sanmıyorum. Boş bir dizi oluşturduysanız, bir şey için varsayılan olur ve ödevden sonra kullanılan bayt sayısından daha yüksek olabilirdi, ancak bu durumda, kopya kurucusu çağrılır ve dizinin başlatılacağını beklerdim. iletilen karakter sayısı. – ventsyv
Bir dizi oluşturduğunuzda, '.length' için istediğiniz uzunluk (Java özelliğindedir) olacaktır. Bu durumda, 'encode()', ne yapacağını söylemez, sadece 'ByteBuffer' için istediğiniz kodlanmış karakterleri döndürür. Diğerleri içine kazandılar ve bu bir uygulama detayı, bu nedenle bu davranış JVM sürümleri ve uygulamaları arasında farklılık gösterecek. –
Tamam, bu mantıklı. – ventsyv
import java.nio.charset.*;
public class ByteArrayTest {
public static void main(String[] args) {
String theString = "hello world";
System.out.println(theString.length());
byte[] byteArray = Charset.forName("UTF-8").encode(theString).array();
System.out.println(byteArray.length);
for (int i = 0; i < byteArray.length; i++) {
System.out.println("Byte " + i + " = " + byteArray[i]);
}
}
}
Sonuçlar: iyi bir Cı-dize olacak gibi
C:\JavaTools>java ByteArrayTest
11
12
Byte 0 = 104
Byte 1 = 101
Byte 2 = 108
Byte 3 = 108
Byte 4 = 111
Byte 5 = 32
Byte 6 = 119
Byte 7 = 111
Byte 8 = 114
Byte 9 = 108
Byte 10 = 100
Byte 11 = 0
dizi boş sonlandırılmış.
(Ama görünüşe göre gerçek nedeni pul pul yöntem array. Muhtemelen büyük bir özenle dışında "üretim" kodunda kullanılmamalıdır. Olduğu)
0 bayt sondaki boş bir sonlandırıcı – Andreas
@Andreas - Yep kadar büyük olduğunu sanmıyorum, muhtemelen haklısınız - [dizi] (http://docs.oracle.com/javase/7 /docs/api/java/nio/ByteBuffer.html#array%28%29), ByteBuffer'in iç arabelleğini döndüren yarı-sahte bir işlemdir ve bu nedenle ne kadar büyük olacağını söyleyemezsiniz. –
@Andreas: Java çalışma zamanı (tahmin edeyim) C cinsinden uygulanmıştır, bu yüzden dizelerin süresiz olarak sonlandırılması uygun olabilir. :-) –
olduğu belgeleri okuyor. –
Ben get ve put yöntemleri kullanmak zorunda kalmadan, destek dizisine herkese açık erişime sahip olduğunuzu şaşırıyorum. – azurefrog