byte数组与java基本对象的转换以及异或^的理解
异或的理解
第一次认识异或是在数组位置交换的时候,可以方便的不使用第三变量,加快运行,这里就单独提一下异或, 详细可参考链接
异或^
1.异或 ^.运算规则就是相同为0,不同为1。进行异或运算时,当前位的两个二进制表示不同则为1相同则为0.该方法被广泛推广用来统计一个数的1的位数!
运算规则:0 ^ 0 = 0; 0 ^ 1 = 1; 1 ^ 0 =1 ; 1 ^ 1 = 0;
按位异或的3个特点:
(1) 00=0,01=1 0异或任何数=任何数
(2) 10=1,11=0 1异或任何数-任何数取反
(3) 任何数异或自己=把自己置0
按位异或的几个常见用途:
(1) 使某些特定的位翻转
例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。
10100001^00000110 = 10100111
(2)实现两个值的交换,而不必使用临时变量。
例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
a = a^b; //a=10100111
b = b^a; //b=10100001
a = a^b; //a=00000110
(3)数组交换代码示例
// 翻转数组
// example: 0x01020304 -> 0x04030201
public static void ReverseByte(byte[] src) {
int mid = src.length / 2; //中间位置
int len = src.length - 1; //数组最后一位
for(int i = 0; i < mid; i++) {
//相互交换
src[i] ^= src[len - i];
src[len - i] ^= src[i];
src[i] ^= src[len - i];
}
}
byte数组与java基本对象的互相转换
1、byte数组转java对象
所有的数组都是低位在前,高位在后
/**
* byte转int
* @Title: bytesToInt
*
* @param: @param src 源数组
* @param: @param offset 起始偏移量
* @return: int
*/
public static int bytesToInt(byte[] src, int offset) {
int value;
value = src[offset] & 0xFF;
value |= ((long) (src[offset + 1] & 0xFF) << 8);
value |= ((long) (src[offset + 2] & 0xFF) << 16);
value |= ((long) (src[offset + 3] & 0xFF) << 24);
return value;
}
/**
* byte转long
* @Title: bytesToLong
*
* @param: @param src 源数组
* @param: @param offset 起始偏移量
* @return: long
*/
public static long bytesToLong(byte[] src, int offset) {
long value = 0;
for(int i = 0; i < 8; i++) {
value |= ((long) (src[offset + i] & 0xFF) << (8 * i));
}
return value;
}
/**
* byte转float
* @Title: byteToFloat
*
* @param: @param src 源数组
* @param: @param offset 起始偏移量
* @return: float
*/
public static float byteToFloat(byte[] src, int offset) {
int value;
value = src[offset + 0] & 0xFF;
value |= ((long) (src[offset + 1] & 0xFF) << 8);
value |= ((long) (src[offset + 2] & 0xFF) << 16);
value |= ((long) (src[offset + 3] & 0xFF) << 24);
return Float.intBitsToFloat(value);
}
/**
* byte转double
* @Title: byteToDouble
*
* @param: @param src 源数组
* @param: @param offset 起始偏移量
* @return: double
*/
public static double byteToDouble(byte[] src, int offset) {
long value = 0;
for (int i = 0; i < 8; i++) {
value |= ((long) (src[offset + i] & 0xff)) << (8 * i);
}
return Double.longBitsToDouble(value);
}
2、java对象转byte数组
转换后所有的数组都是低位在前,高位在后
/**
* int转byte
* @Title: intToBytes
*
* @param: @param value
* @return: byte[]
*/
public static byte[] intToBytes(int value) {
byte[] result = new byte[4];
for (int i = 0; i < 4; i++) {
result[i] = (byte) ((value >> (i * 8)) & 0xFF);
}
return result;
}
/**
* long转byte
* @Title: longToBytes
*
* @param: @param value
* @return: byte[]
*/
public static byte[] longToBytes(long value) {
byte[] result = new byte[8];
for (int i = 0; i < 8; i++) {
result[i] = (byte) ((value >> (i * 8)) & 0xFF);
}
return result;
}
/**
* float转byte
* @Title: floatToBytes
*
* @param: @param f
* @return: byte[]
*/
public static byte[] floatToBytes(float f) {
int fbit = Float.floatToIntBits(f);
return intToBytes(fbit);
}
/**
* double转byte
* @Title: doubleToBytes
*
* @param: @param d
* @return: byte[]
*/
public static byte[] doubleToBytes(double d) {
long lbit = Double.doubleToRawLongBits(d);
return longToBytes(lbit);
}
总结
计算机在位操作上面比简单计算要快的多,多用于协议报文转换的场景