2020-1-6
计算机排列字节的方式有大端法(BE)和小端法(LE),数据的加载从地址的低到高,顺序加载。
计算机排列字节的方式有大端法(BE)和小端法(LE),数据的加载从地址的低到高,顺序加载。
//存储的数据为0xABCDEF...
//存储地址有0x100,0x101,0x102...
//大端法对应存储AB,CD,EF...每次顺序拿地址,左右拼接起来。
//小端法对应存储...,EF,CD,AB,每次拿一个都会追加到前边。
//一般不需要考虑
常见编码
ASCII:标准的单字节,美国码。
ISO8859-1:单字节增强码,包容ASCII,欧洲码。
GB2312:中国规定,6763个通用汉字
GBK:中国规定,21886个汉字
GB18030:中国规定,70,244个汉字,向上兼容
Unicode:万国码,范围0x0~0xFFFF,是一种规定,保存方式由UTF-8,UTF-16,UTF-32来实现。
\u7231:视为Unicode字符,对应中文"爱"=U+7231,
爱:也视为Unicode字符,有分号结尾
UTF-32:直接保存这16进制编号地址为二进制数。
UTF-16:U+0000~U+FFFF的范围用两个字节,剩下的用四个字节
UTF-8:可变字节。
0x00~0x7F,单字节范围对应ASCII,0XXXXXX
0x80~0x7FF,两个字节,110XXXXX,10XXXXXX
0x800~0x7FFF,三个字节,1110XXX,10XXXXXX,10XXXXXX
//...
//例子,砍六填充到8
//0x7231
//0111,0010,0011,0001
//0111,001000,110001,
//11100111,10001000,10110001,
URL编码:URL只支持字母数字特殊符号以及一些保留字,不包括双引号,要使用Base64进行编码处理。
java中char使用的unicode编码来存储。
Charset.availableCharsets().keySet();//获取java支持的所有编码
StandardCharsets.UTF_8//获取UTF-8等常用的静态字符串,jdk1.6以及以下是没有的
字符串类:本质上用char数组来保存数据,打印出来是双引号包裹的字符串。
String://final修饰,处理都是重新赋值新的字符串,构建以及转化,索引以及查找,比较以及复制,拆分,大小写转化
//String是引用传递,但值不可以改。
//String A ="1";引用传向对象B,再修改B的值,d
//String B = A;
//String B =B+"2";//其中操作是常量池创建新字符串"12"再修改B的引用。A的引用还是指向"1"
StringBuilder://可变不安全字符串类,默认char数组长度16,
//追加,//插入,长度,索引,翻转,截取,替换等功能
StringBuffered://可变安全字符串类,是底层安全的StringBuilder对象
//方法和StringBuider一样
//三者的优选方式:StringBuider最优先,线程安全考虑StringBuffered,简易使用则用String
字符串之间的比较:
//常量池保存唯一的字符串(没有则创建),并返回引用。对字符串的操作都返回新增字符串的地址。
Stringa="1";//a的值为常量池地址,
Stringb=newString("1");//b的值为堆地址
Stringc=String.valueOf(a);//继承,a.toString返回的a对象引用。
//==比较引用指向的地址位置。上边堆地址值肯定不等于常量池地址值。
//equals比较的是字符串的内容。
Stringstr="a"+"b";//编译后,String str = "ab";
finalStringa="a";
Stringb=a+"b";//结果,b =="ab";
Stringc=(newStringBuilder()).append(a).append(b).toString();//String c = a+b;jdk8的编译器自动优化
大批量的字符串拼接效率:
+ //字符串拼接
concat //String对象的concat方法
StringUtils.join(Object[]objs)//apache.commons的字符串拼接方法,就是用的StringBuilder拼接并且返回String
StringBuffer.append()
StringBuilder.append()
//StringBuilder>StringBuffer>String对象.concat>+
字符串转化:
//java内所有的字符串都是unicode字符串。
//ISO-8859-1单字节文件,可以直接转化为unicode和gbk等,常见的全英文文件不受编码影响。
//非单字节文件,必须用对应的编码保存,不然变全乱码文件。
//不同的非单字的字节编号对应的值都不同,GB18030在UTF-8的是不对应的,国标系文件向上兼容。如果想值转化,考虑字符映射表
//字符串的本质就是byte[],大部分不同的数据类型是可以转化的,转化UTF系列是不可逆的。
"".getBytes(encoding);//获取指定编码的字符串,不传编码就拿本地编码
newString(byte[],encoding);//byte[]转化为字符串
//举个栗子:
byte[]bytes="我爱你".getBytes(GBK);
System.out.println("-----转化为IBM855和转回GBK");
Strings1=newString(bytes,"IBM855");
Strings2=newString(s1.getBytes("IBM855"),GBK);
System.out.println(s2);
System.out.println("-----转化为ISO-8859-1和转回GBK");
s1=newString(bytes,"ISO-8859-1");
s2=newString(s1.getBytes("ISO-8859-1"),GBK);
System.out.println(s2);
System.out.println("-----转化为UTF-8和转回GBK");
s1=newString(bytes,"UTF-8");
s2=newString(s1.getBytes("UTF-8"),GBK);
System.out.println(s2);
//web服务接收的参数就是乱码,一般是直接过滤器过滤掉非UTF-8编码的请求。
//文件上传功能传递文件名乱码,tomcat会自动用ISO-8859-1转化为String文件名。可选择转化为ISO的byte数组,在转化UTF-8字符串。缺点每次都要处理。
字符串都保存在常量池中,常量池的位置在jdk1.6,1.7,1.8的位置不同。
java.lang.OutOfMemoryError:PermGenspace//永久代内存不足,jdk1.6永久代放在堆外
java.lang.OutOfMemoryError:Javaheapspace//堆内存不足,jdk1.7永久代放在堆中
java.lang.OutOfMemoryError:Metaspace//元空间内存不足,jdk1.8永久代取消,被元空间替换,本地内存中
Unicode字符串的处理与优化:
chara='\uabcd' //在java中代表一个char
Stringb="\\uabcd"//unicode字符串固定长度6
Stringc="ꯍ"//unicode字符串固定长度8
//测试中,使用了subString(很低),new StringBuilder,StringBuilder替换指定位置,和char数组。Pattern类(性能低,在600W字节的测试数据中,一秒处理100个左右),
//最终测试,还是使用了char[]来处理。优点,占用时间最少,空间使用最少(字符串长度600W,目标容器600W和一个长度4的char数组)。
个人项目的测试与学习
//访问路径:https://github.com/JunOneWolf/test2learn
字符串和unicode的处理:cn.jof.test2020_1_15_testUnicode
//字符串拼接性能检测:cn.jof.test2020_1_16_testStringConcat。
//检测文件的编码工具类:cn.jof.utils.EncodingDetect