Java 基本数据类型 && 位运算
1. Java基本数据类型
1.1 数据类型示意图
类型 | 字节数 | 范围 |
byte | 1 | -128~127 |
short | 2 | -32768~32767 |
int | 4 |
-231~231-1 |
long | 8 | -263~263-1 |
float | 4 | |
double | 8 | |
bolean | 1 | |
char | 2 |
(ps: byte、char、short在运算时会自动提升到 int 类型)
1.2 隐式转换&显式转换
隐式类型转换:从存储范围小的类型到存储范围大的类型转换。
显示类型转换:强制类型转换,从存储范围大的类型到存储范围小的类型转换。
2. 位运算
2.1 位运算符
运算符 | 说明 |
& | 与 |
| | 或 |
^ | 异或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
>>> | 无符号右移 |
【&&与&的区别】
&&存在短路,&通过位运算完成,无短路操作
2.2 原码、反码、补码
【原码】
符号位加上数字的二进制表示,第一位为符号位(0为正数,1为负数)
byte 类型的 +7 和 -7 的原码如下
+7:00000111
-7: 10000111
【反码】
正数的反码与原码相同,负数的反码符号位不变,其余位数取反。
byte 类型的 +7 和 -7 的反码如下
+7:00000111
-7: 11111000
【补码】
正数的原码、反码、补码相同,负数的反码为原码取反加1
byte 类型的 +7 和 -7 的补码如下
+7:00000111
-7: 11111001
2.3 把 long 数据转换成字节数组相互转换
1 /** 2 * 1. 把long数据转换成字节数组 3 * 2. 把字节数组数据转换成long 4 */ 5 public class TransDataType { 6 //把long数据转换成字节数组 7 public static byte[] long2Bytes(long lon) { 8 byte[] bytes = new byte[8]; 9 for (int i = 0; i < 8; i++) { 10 bytes[i] = (byte) (lon >> (56 - 8 * i)); 11 } 12 return bytes; 13 } 14 15 //把字节数组数据转换成long 16 public static long bytes2Long(byte[] bytes) { 17 long val = 0; 18 for (int i = 0; i < 8; i++) { 19 long lon = ((long) bytes[i] & 0xff) << (56 - 8 * i); 20 val += lon; 21 } 22 return val; 23 } 24 25 public static void main(String[] args) { 26 byte[] bytes = long2Bytes(-1275555); 27 for (int i = 0; i < bytes.length; i++) { 28 System.out.println(bytes[i]); 29 } 30 31 System.out.println("=============================================="); 32 33 long l = bytes2Long(bytes); 34 System.out.println(l); 35 } 36 }
2.4 将 byte 变换成无符号的整数(0 ~ 255 , 正数不变)
1 /** 2 * 将byte变换成无符号的整数(0 ~ 255 , 正数不变) 3 */ 4 public class TransByte2Int { 5 public static int bytes2Int(byte by){ 6 int a = by&0xff; 7 return a; 8 } 9 10 public static void main(String[] args) { 11 int i = bytes2Int((byte) -128); 12 System.out.println(i); 13 } 14 }
2.5 定义函数,取出整数内存中的存储形态对应的16进制字符串与2进制字符串
1 /** 2 * 定义函数,取出整数内存中的存储形态对应的16进制字符串 3 * 定义函数,取出整数内存中的存储形态对应的2进制字符串 4 */ 5 public class TransInt2String { 6 //定义函数,取出整数内存中的存储形态对应的16进制字符串 7 public static String int2HexString(int in) { 8 9 StringBuilder builder = new StringBuilder(); 10 char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 11 for (int i = 0; i < 8; i++) { 12 char c = chars[in >> (i * 4) & 0x0f]; 13 builder.insert(0, c); 14 } 15 return builder.toString(); 16 } 17 18 //定义函数,取出整数内存中的存储形态对应的2进制字符串 19 public static String int2BinString(int in) { 20 21 StringBuilder builder = new StringBuilder(); 22 char[] chars = {'0', '1'}; 23 byte[] bytes = new byte[8]; 24 for (int i = 0; i < 32; i++) { 25 builder.append(chars[in >> (31 - i) & 0x01]); 26 } 27 return builder.toString(); 28 } 29 30 public static void main(String[] args) { 31 32 System.out.println("=============================================="); 33 String s1 = int2HexString(100); 34 System.out.println(s1); 35 36 System.out.println("=============================================="); 37 String s2 = int2BinString(100); 38 System.out.println(s2); 39 } 40 }
2.6 有5亿整数(非负),去重计算不同整数的个数,300M内存
1 package com.share.java.test; 2 3 import org.junit.Test; 4 5 /** 6 * 有5亿整数(非负),去重计算不同整数的个数,300M内存 7 * int的最大值为Integer.MAX_VALUE (2147483647/8/1024/1024=255) 8 * 一个byte有8位,定义长度为 Integer.MAX_VALUE/8 +1 的byte数组 9 * 每一位都表示一个数 10 * 遍历int数组 11 * 通过 整数/8 确定行,用过 整数%8 确定列 12 * 通过得到的行数和列数确定的位置,判断该位置是否存在1 13 * 若不存在,将该位置设置为1,count加1 14 */ 15 public class TestCalc { 16 17 @Test 18 public void testCountUnique() { 19 int[] arr = {0, 1, 2, 3, 4, 1, 2, Integer.MAX_VALUE}; 20 System.out.println(countUnique(arr)); 21 } 22 23 /** 24 * 去重统计整数个数 25 */ 26 public static int countUnique(int[] arr) { 27 //计算行数 28 int rows = Integer.MAX_VALUE / 8 + 1; 29 30 //初始化字节数组 31 byte[] bytes = new byte[rows]; 32 33 //计数器 34 int count = 0; 35 // 36 for (int i : arr) { 37 //定位行数 38 int row = i / 8; 39 //定位列数 40 int col = i % 8; 41 // 42 int r = (byte) (bytes[row] & (1 << col)); 43 if (r == 0) { 44 count++; 45 bytes[row] = (byte) (bytes[row] | (1 << col)); 46 } 47 } 48 return count; 49 } 50 }
且将新火试新茶,诗酒趁年华。