我想在Java中以文本形式将(正)原始long转换为byte[]
。
例如,简单的方法是:123 => "123" => [49, 50, 51]
然而,将long转换为String
堆 - 分配String
,我试图避免这个用于我的无GC库。我宁愿直接在预先分配的字节数组上渲染它。
因此,我的问题是如何直接从long转换为byte[]
表示,如果我使用String构造函数调用(对于上面的示例),则给出“123”。为了澄清,我不打算将long编码为二进制形式的byte[]
,而是文本形式。
谢谢! Ñ
答案 0 :(得分:4)
这个简单的程序:
long l = 123;
int size = (int)(Math.log10(l)+1);
byte[] array = new byte[size];
for (int i = 0; i < size; i++) {
long temp = (long) Math.pow(10, size - i - 1);
array[i] = (byte) ((l / temp) + 48);
l = l % temp;
}
System.out.println(Arrays.toString(array)); // [49, 50, 51]
我已经以毫秒为单位对当前时间进行了测试并按预期工作:
long l = System.currentTimeMillis();
...
System.out.println(Arrays.toString(array));
输出:
1406485727149
[49, 52, 48, 54, 52, 56, 53, 55, 50, 55, 49, 52, 57]
答案 1 :(得分:3)
要编写它而不使用byte []或使用相当昂贵的Math.pow和Math.log,您可以执行以下操作。
public static void toStream(OutputStream os, long l) throws IOException {
toStream0(os, l / 10);
os.write((int) ('0' + l % 10));
}
private static void toStream0(OutputStream os, long l) throws IOException {
if (l == 0) return;
toStream0(os, l / 10);
os.write((int) ('0' + l % 10));
}
toStream(System.out, System.currentTimeMillis());
打印
1406486588664
如果您正在写ByteBuffer,请使用put(
或StringBuilder使用append((char)
您可以考虑使用更大的基数来缩小数字。
base 36: hy4p6ugr
base 16: 147791288bb
base 10: 1406485563579
答案 2 :(得分:2)
我认为这就是你所要求的(?):
static int toChars(long num, byte[] buffer) {
if (num < 0) throw new IllegalArgumentException();
int length = 0;
do {
buffer[length++] = (byte)(num % 10 + '0');
} while ((num /= 10) != 0);
for (int i = 0, mid = length >> 1, j = length - 1; i < mid; i++, j--) {
byte tmp = buffer[i];
buffer[i] = buffer[j];
buffer[j] = tmp;
}
return length;
}
用法:
byte[] buffer = new byte[19]; // 19 = enough for everything up to Long.MAX_VALUE
int length = toChars(51239827493284L, buffer);
System.out.println(new String(buffer, 0, length,
java.nio.charset.StandardCharsets.US_ASCII));
答案 3 :(得分:1)
据我所见,没有诀窍。
public class Test {
public static void main(String[] args) {
byte [] result = new byte[6];
convert( 123456, result );
System.out.println( new String( result ) );
}
public static void convert( long n, byte [] array ) {
for (int i = size( n ) - 1; i >= 0; --i) {
array[i] = (byte)(n % 10 + '0');
n = n / 10;
}
}
public static int size( long n ) {
int ret = 0;
while (n > 0) {
ret++;
n /= 10;
}
return ret;
}
}
请注意,这仅适用于正数,并且不检查数组是否足够大以适应数字,您应该在实际代码中执行这两项操作。它无法处理n=0
中的小问题。
您可以避免使用size()
方法将数组填充到前面,然后将其翻转,但是我不太确定它会为您提供任何性能方面的信息。 #39; d是一个噩梦。
答案 4 :(得分:1)
您可以预先将byte[]
分配给最长的长(最长的长度为20个字符),然后将长整齐转换为该数组。
当然,如果你不想在数字17上浪费20个字符,你可以快速计算出长数中的字符数(看它是否大于10 ^ 18,那么如果它大于10 ^ 18等...你可以对数字位进行二进制搜索。)