Java学习树--5字符串的学习

字符串定义

       String s="lin";
       String l=new String("lin");
       String k=new String(new char[]{'l','i','n'});

其中字符串s,l都是字符串变量,他们是不同的引用,但是指向相同的字符串常量lin,使用==判断返回false.


字符串的构造函数还有接受 char[],byte[]数组的重载方法,同时可以byte[]重载的数组还可以指定字符集。String​(byte[] bytes, String charsetName)

字符串的常用方法

字符串的静态方法String.format(format,...args)

字符串的实例方法
strim() 最新的删除前后空格的方法是strip()不过Java11版本以上
split() 返回一个字符串数组,使用输入的切割符
indexOf() 返回寻找字符或字符串的索引
substring()

可改变的字符串

StringBuffer
StringBuilder


这些可变字符串类型,都支持append() insert()方法,


StringJoiner() 用于构造拥有指定前缀和后缀,被分隔符隔开的字符串,1.8版本可用
比如[George:Sally:Fred],这些字符串的前缀是[,后缀是],分隔符是:

 StringJoiner sj = new StringJoiner(":", "[", "]");
 sj.add("George").add("Sally").add("Fred");
 String desiredString = sj.toString();

StringJoiner(charSequence delimiter) StringJoiner(charSequence delimiter,charSequence prefix,charSequence suffix) 最常用的方法是add()添加元素

字符串与其他数据类型的转换

字符串静态方法,String.valueOf(T t) 重载基本类型的转换成为字符串,还有char[]数组。

charSequence接口

这些接口是定义了字符值的可读字符序列,它声明了字符序列常用的方法chars() charAt() isEmpty() length()等方法

字符串实现了该个接口,字符串内部使用一个字节数组存储字符
private final byte[] value;
private final byte coder; 值得字符编码集,如UTF8

字符串与字符编码

The Java platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes.
Java平台使用UTF-16表达char数组,字符串stringBuffer类。


U+0000 to U+10FFFF到这个范围是合法代码点范围,成为Unicode标量值,超过U+10FFFF成为补充字符。
U+0000-U+10FFFF是官方规定的Unicode编码范围


详细关于字符集的介绍,博客链接


但是Java中
Charset.defaultCharset() ;默认的字符集UTF8
System.getProperty("file.encoding"); 文件的默认编码格式UTF8
System.getenv("user.language"); ;默认null


在Java平台中,虽然字符串和字符数组使用的是UTF16编码格式,但是当字符串转换成字节数组时,getBytes()会依据平台的默认字符集进行编码转换。


中文编码在不同字符集中的区别,BMP是BOM
知乎字符解答
字符解答


BMP平面又称第0平面,是Unicode的一个编码区段,范围是U+0000--U+FFFF


UTF16中文编码是2字节,UTF8一般是3字节,GBK一般是2字节,常规的英文都是1字节,但是UTF16是规定所以的字符都是使用2字节编码
Unicode Character set简称UCS,只规定了如何对字符进行编码,但是没有规定如何保存和传输字符。比如UTF8规定了小于FFFF的中文字符使用3字节存储,而UTF16规定使用2字节存储。


UTF的字节序,BOM,Byte Order Mark
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?
Unicode规范中推荐的标记字节顺序的方法是BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。 UTF16的字节序,大端和小端


String#getBytes() 方法,会将字符转换成为字节,会按照编码方式不同,转换成为不同字节数组,默认的编码方式是采用平台的默认编码UTF8
但是如果传入String#getBytes("GBK")会按照中文编码方式进行编码


如果传入的String#getBytes("UTF-16")会使用前2个字节存储字节序,UTF16采用2字节存储字符,多余的两个字节是记录字节的存储顺序,及字节序,默认的字节序是大端,及UTF-16BE


String#getBytes("UTF-16BE") String#getBytes("UTF-LE16") 传入的参数添加BE,LE,那么会省去前面存储字节序的2个字节,UTF-16BE的前2字节分别是-2,-1.


HTML中关于字符集的相关属性
Accept-Charset:浏览器申明自己接收的字符集,通常就是我们说的编码方案,比如UTF8,GBK
Accept-Language:浏览器申明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等
Content-Type:WEB服务器告诉浏览器自己响应的对象的类型和字符集。例如:Content-Type: text/html; charset='gb2312'

Character类的使用

静态常量
Character.MAX_CODE_POINT 返回最大的Unicode码点,Unicode code point,值是U+10FFFF
Character.MAX_VALUE 返回该字段最大的值,是'\uFFFF'
Character.MAX_RADIX 最大基数是36-2,可在字符串转换之间的最大基数

Character中有许多的静态方法,判断一个字符是否是某一个类型的字符,比如数字,字母,ISO控制字符,能否作为Java标识符等,但是通常只对不超过\uffff字符有效,超过这个范围,就必须用重载的参数int类型的方法。

isDigit​(char ch)
isLetter​(char ch)
isLetterOrDigit​(char ch)
isLowerCase​(char ch)
isSpace​(char ch) 对\t,\n,\f,\r,' ' 有效
isWhitespace​(char ch) 对于Java规定的空白字符有效
isUpperCase​(char ch)


博客
isValidCodePoint​(int codePoint) 输入codePoint,判断是否是标准的码元,范围是0-0x10ffff(1114111),不超过这个范围即为有效。一个字符对应的Unicode值。


Character.codePointCount(string,begin,end);Character.codePointCount(char[],offset,count)计算一个char数组或者字符串中Unicode的数量,主要是计算数组中的数量


Character.toCodePoint方法是将一个unicode的高位和低位进行结合后拼接输出,例如😠对应的unicode的是\uD83D\uDE20,可以调用tocodePoint('\ud83d','\ude20')然后输出笑脸的Unicode十进制值。


获取一个字符的对应的Unicode值
Character.codePointAt(char[],index) 返回char[index]对应字符的Unicode值,十进制形式。

String h="☺";
char[] x=h.toCharArray();
System.out.println(h.toCharArray().length); //1
System.out.println(Character.codePointAt(x,0)); //input:9786
       char v='\u263a';
        System.out.println(v); //☺
        System.out.println(Integer.toHexString(9786)); // 263a

编码格式的转换

字符编码与解码都在charset包类下,具体有Charset,CharsetDecoder,CharsetEncoder这三个主要的工作类。


Charset类实现了Java支持所以平台的字符集,US-ASCII,IOS-8859-1,UTF-8,UTF-16LE|BE,UTF-16。
常用的静态方法
Charset.forName()返回一个charset,Charset.isSupported()是否支持编码格式,Charset.defaultCharset()


Charset还要两个便利的解码和编码的方法,将字节转换成为Unicode字符,或者相反。
Charset#encode() Charset#decode() 使用到的类型是CharBuffer,ByteBuffer


decode解码,将某个字符集的字节解码成为Unicode字符
encode编码,将Unicode字符转换成为某个字符集的字节

不同格式的转换就是将某一个字符集的字节流转换成为Unicode字符,然后再通过Unicode字符转换成为另一个字符集的字节流。


获取编码器和解码器,使用字符集获取相关实例 Charset#newDecoder() 解码器最重要的方法就是decode() Charset#newEnocder()
某个文件的格式是GBK,想要转换成为UTF8,需要打开文件,以字节序列的形式读取文件,然后GBK的解码器将字节流转换成为Unicode字符序列,然后用UTF8编码器将Unicode字符序列转换成为字节序列,然后写入文件中。

字符串与正则表达式的方法

Java中有关正则表达式有两个重要的类。
Pattern,Matcher。
其中Pattern是正则表达式的编译类,Matcher是获得正则表达式搜查的结果。


以上两个类都没有构造函数,只有静态方法构建类
具体的正则表达式可以看Java文档,Pattern类的描述。


Pattern.compile​(String regex).Matcher(charSequence input)


Pattern类的实力方法有flags() 返回正则表达式的特性标志,比如全局匹配,忽略大小写
Pattern#pattern()返回正则表达式
Pattern#split(charSequence input) 依据正则表达切割字符串,返回字符串数组。


组的概念,正则表达式例((A)(B(C))),这里一共有4个组,((A)(B(C))),(A),(B(C)),(C)
groupCount()获取匹配组数量。


通过Matcher#group(int index)就会返回每个组匹配字符串的结果,因为正则表达式第一个组是整个正则表达式,所以group(0)永远会有结果返回。
其次,也可通过原字符串截取匹配结果,可以通过Matcher#start(),Matcher#end()方法获取匹配结果的索引值


Matcher#find() 会逐步进行匹配,整个方法同迭代器中的hashNext()方法,用法也类似,用find方法判断,在循环内使用group(0)获取匹配结果。


Matcher#matches() 会整个字符串与表达式匹配,返回布尔值


Matcher#replaceAll() Matcher#replaceFirst() Matcher#usePattern() 更改匹配正则表达式
 Pattern p = Pattern.compile("cat");
 Matcher m = p.matcher("one cat two cats in the yard");
 StringBuffer sb = new StringBuffer();
 while (m.find()) {
     m.appendReplacement(sb, "dog");
 }
 m.appendTail(sb);
 System.out.println(sb.toString()); //one dog two dogs in the yard . 

appendReplacement()主要就是利用缓存区,替换新字符,appendTail()在前者方法调用后,再调用,依据前者的模板调用

posted @ 2021-06-07 17:19  lfcom  阅读(97)  评论(0编辑  收藏  举报