这里写目录标题
创建字符串
我们常用的构造字符串的方法有三种:
方法一:直接引用:
String str ="abcdef";
方法二:new 一个字符串对象:
String str2 =newString("Hello Bit");
方法三:将字符数组转化为字符串:
char[] array ={'a','b','c'};String str3 =newString(array);
字符串引用
注意事项:
- 上面方法一的 abcdef 是一个常量,类型是 String 。str 是对这个字符串的引用。
内存分布如图所示:
这里的 String 也是引用类型。
代码中的引用
对于如下代码:
String str1 ="Hello";String str2 = str1;
这段代码的内存分布如图所示:
要注意的是:String str2 = str1; 并不是 str2 引用了 str1 ,而是指向了和 str1 一样的地址。所以,修改 str1 的值,str2 的值不受影响:
publicstaticvoidmain(String[] args){String str1 ="abcdef";String str2 = str1;System.out.println(str1);System.out.println(str2);
str1 ="Lockey";System.out.println(str1);System.out.println(str2);}
运行结果如下:
因为改变的是 str1 的引用,所以与 str2 无关。
比较字符串相等
如果是两个 int 类型的话,可以直接用 == 比较,但如果是两个字符串类型的话,就有区别了:
代码一
publicstaticvoidmain(String[] args){String str1 ="hello";String str2 ="hello";System.out.println(str1 ==str2);}
运行结果如下:
代码二
publicstaticvoidmain(String[] args){String str1 =newString("Hello");String str2 =newString("Hello");System.out.println(str1 == str2);}
运行结果如下:
这是因为代码一和代码二的内存布局不一样:
代码一的内存布局:
因为字符串 Hello 是一个常量字符串,所以这里这两个的指向是同一个。所以是 true 。
代码二的内存布局:
因为是 new 了一个对象,所以就相当于在堆山又开辟了一块内存。所以引用的对象不一样。这两个对象仅仅是内容相同。
String 使用 == 比较并不是在比较字符串内容, 而是比较两个引用是否是指向同一个对象。
字符串的比较方法
在 Java 当中比较字符串的时候只能用 String 提供的 equals 方法。
publicstaticvoidmain(String[] args){String str1 =newString("Hello");String str2 =newString("Hello");System.out.println(str1.equals(str2));}
运行结果如下:
equals 使用注意事项
如果要比较 str 和 Hello 两个字符串是否相等,有两种写法:
String str =newString("Hello");// 写法一System.out.println(str.equals("Hello"));// 写法二System.out.println("Hello".equals(str));
这两种写法更推荐写法二,因为如果写法一的 str 是 null 的话,代码就会报错。而方法二就不会报错。
字符串常量池
对 String 类的两种实例化方法:直接赋值,new 一个新的 String
直接赋值
String str1 ="hello";String str2 ="hello";String str3 ="hello";System.out.println(str1 == str2);// trueSystem.out.println(str1 == str3);// trueSystem.out.println(str2 == str3);// true
字符串常量池就是里面存放字符串常量,从 JDK1.8 开始就把它放在了堆上面。放在常量池里面方便使用。内存分布如下图:
它们引用的都是同一个对象,因为在 JVM 底层会自动维护一个对象池(字符串常量池)所以这里的比较也就变成了 true 。
采用构造方法
类对象使用构造方法是标准做法,如下代码:
String str =newString("Hello");
这里的 Hello 是每次都会创建的对象,当然也可以通过 intern 关键字来完成入池操作。如下代码:
publicstaticvoidmain6(String[] args){String str1 =newString("Hello");String str2 =newString("Hello");System.out.println(str1.equals(str2));}
运行结果如下:
使用入池之后就是这样:
publicstaticvoidmain(String[] args){String str1 =newString("hello").intern();String str2 ="hello";System.out.println(str1 == str2);}
运行结果如下:
因为都放在了常量池,所以就过就是 true 。
字符串不可变
字符串是不可改变的,就算使用 + 也只是改变了字符串的引用,就像下面这样:
publicstaticvoidmain(String[] args){String str ="hello";
str = str +" world";
str +="!!!";System.out.println(str);}
运行结果如下:
但是这段代码的内存图如下所示:
它的结果只是指向了最后一个字符串。
修改字符串
如果要修改字符串的话,就只能借助原有的字符串重新创建字符串:
publicstaticvoidmain(String[] args){String str1 ="hel";String str2 = str1+"lllllll";System.out.println(str2);}
运行结果如下:
字符,字节与字符串
字符与字符串
把字符数组转化为字符串
通过 new 一个字符串完成转化:
publicstaticvoidmain(String[] args){char[] val ={'a','b','c','d','e','f'};String str =newString(val);System.out.println(str);}
运行结果如下:
当然 new 的时候也可以选择从某个位置到某个位置创建字符串:
publicstaticvoidmain(String[] args){char[] val ={'a','b','c','d','e','f'};String str1 =newString(val,1,3);System.out.println(str1);}
运行结果如下:
把字符串变成字符
publicstaticvoidmain(String[] args){String str2 ="hello";char ch = str2.charAt(2);System.out.println(ch);}
这里的 2 是下标 2 ,下标是从 0 开始的。运行结果如下:
当然,也能把整个字符串变成字符数组:
publicstaticvoidmain(String[] args){String str2 ="hello";char[] ch1 = str2.toCharArray();System.out.println(Arrays.toString(ch1));}
运行结果如下:
判断字符串是否全是数字
通过将 String 转化为字符,然后利用 Character 自带的方法 isDigit() 来判断:
publicstaticbooleanisNumberChar(String s){for(int i =0; i < s.length(); i++){char c = s.charAt(i);boolean flag =Character.isDigit(c);if(flag ==false){returnfalse;}}returntrue;}publicstaticvoidmain(String[] args){String str ="1234567890";System.out.println(isNumberChar(str));}
运行结果如下:
字节与字符串
将字节变成字符串
还是通过 new 一个字符串来完成,而且也可以从某个位置完成字符串的转化:
publicstaticvoidmain(String[] args){byte[] bytes ={97,98,99,100};String str =newString(bytes);System.out.println(str);String str2 =newString(bytes,1,3);System.out.println(str2);}
字符串转化为字节
通过将字符串转化为字节数组来完成:
publicstaticvoidmain(String[] args){String str ="abcdef";byte[] bytes = str.getBytes();System.out.println(Arrays.toString(bytes));}
这里是转化为编码。
字符数组和字节数组的区别
- 字节数组适合在网络传输 数据存储这样的场景下使用 更适合针对二进制数据来操作。
- 字符数组更适合组队文本数据来操作,尤其是包含中文的时候。
字符串常见操作
字符串比较
字符串的相等比较
通过 String 的 equals 方法来完成对字符串的比较:
publicstaticvoidmain(String[] args){String str1 ="abcdef";String str2 = str1;System.out.println(str1.equals(str2));}
运行结果如下:
忽略大小写的字符串比较:
publicstaticvoidmain(String[] args){String str1 ="abc";String str2 ="Abc";System.out.println(str1.equalsIgnoreCase(str2));//equalsIgnoreCase 忽略大小写的情况System.out.println(n);}
运行结果如下:
字符串的大小比较
通过对字符的比较从而实现对字符串大小的比较:
publicstaticvoidmain(String[] args){String str1 ="abc";String str2 ="Abc";int n = str1.compareTo(str2);//这里的比较有三种情况:大于0 小于0 等于0System.out.println(n);}
运行结果如下:
字符串查找
判定一个字符串中是否有指定内容存在:
contains()
这里是从左往右查找,找到第一个字符出现的位置,找到为 true 找不到为 false 。
publicstaticvoidmain(String[] args){String str ="ababcabcd";String tmp ="abc";boolean flag = str.contains(tmp);System.out.println(flag);}
运算结果如下:
indexOf()
这个方法是返回第一次出现的下标位置,也可以再加一个参数,从下标为 n 的位置去寻找:
publicstaticvoidmain(String[] args){String str ="ababcabcd";String tmp ="abc";int index = str.indexOf(tmp);System.out.println(index);}
lastIndexOf()
这里就是从后往前查找,也可以加一个参数从第 n 个下标往前查找。返回的也是下标:
publicstaticvoidmain(String[] args){String str ="ababcabcd";String tmp ="abc";int index = str.lastIndexOf(tmp);System.out.println(index);}
运行结果如下:
判断是否是某个字符开头结尾
判断某个字符开头:startsWith() 至少一个参数,用来判断是否是这个参数开头的,也可以再加一个参数,表示从下标 n 的位置查找:
publicstaticvoidmain(String[] args){String str ="ababcabcd";String tmp ="abc";System.out.println(str.startsWith("a",4));}
运行结果如下:
判断某个字符结尾:和开头的方法一样:
publicstaticvoidmain(String[] args){String str ="ababcabcd";String tmp ="abc";System.out.println(str.endsWith("cd"));}
运行结果如下:
字符串的替换
全部替换指定字符
使用 replace 方法可以全部替换:
publicstaticvoidmain(String[] args){String str ="ababcabcdabcde";String tmp = str.replace("ab","tp");System.out.println(tmp);}
运行结果如下:
替换第一个字符
使用 replaceFirst 方法完成对第一个字符的替换:
publicstaticvoidmain(String[] args){String str ="ababcabcdabcde";String ret = str.replaceFirst("ab","tp");System.out.println(ret);}
运行结果如下:
字符串拆分
将字符串全部拆分
通过 split 方法,传入根据某个字符拆分。就可以全部拆分了:
publicstaticvoidmain(String[] args){String str ="name=zhangsan&age=19";String[] strings = str.split("&");for(String s:strings){System.out.println(s);String[] ss = s.split("=");for(String st:ss){System.out.println(st);}}}
这里进行了两次拆分,第一次是通过 “&” 来拆分,第二次是通过 “=” 来拆分。运行结果如下:
将字符串拆分为 n 组
这里也还是通过 String 的 split 方法,不过要加一个参数来说明分为几组:
publicstaticvoidmain(String[] args){String str ="192.168.1.1";String[] strings = str.split("\\.",3);for(String s:strings){System.out.println(s);}}
这里是根据 “.” 来分割,所以就要通过转义字符 “\” 来完成。后面的参数说明分割为三组。
运行结果如下:
一次根据多个分隔符进行分割
还是通过 split 来进行分割,不过分割的时候要用符号 “|” 来隔开分隔符。
publicstaticvoidmain(String[] args){String str ="Ja&va#30 12&21#he#ll&o";String[] tmp = str.split(" |&|#");for(String s:tmp){System.out.println(s);}}
运行结果如下:
字符串的截取
截取到结束
通过 String 的方法 substring() 方法来完成对字串的提取。给定一个下标,从下标出提取:
publicstaticvoidmain(String[] args){String str ="abcdefg";String tmp = str.substring(2);System.out.println(tmp);}
运行结果如下:
截取到某个位置
还是通过 substring() 方法,不过要再加一个参数 n 用来表示截取到某个位置:
publicstaticvoidmain(String[] args){String str ="abcdefg";String tmp1 = str.substring(2,5);System.out.println(tmp1);}
运行结果如下:
去除字符串左右的空格
通过方法 trim 来完成对空格的去除:
publicstaticvoidmain(String[] args){String str =" abc def ";String tmp = str.trim();System.out.println(tmp);}
运行结果如下:
字符串大小转化:
把字符串全部转化为大写
通过 String 方法 toUpperCase() 完成转化:
publicstaticvoidmain15(String[] args){String str ="abcdefBFEG";String ret = str.toUpperCase();System.out.println(ret);}
运行结果如下:
把字符串全部转化为小写
也是通过方法 toLowerCase() 来完成转化:
publicstaticvoidmain(String[] args){String str ="abcdefBFEG";String tmp = str.toLowerCase();System.out.println(tmp);}
运行结果如下:
字符串的拼接
通过 String 的方法 concat 来完成拼接:
publicstaticvoidmain(String[] args){String str ="abcd";String ret = str.concat("ef");System.out.println(ret);}
运行结果如下:
要注意的是,这里拼接之后的字符不入池。
判断字符串是否为空
这里也是通过 String 的方法 isEmpty() 来完成判断:
publicstaticvoidmain(String[] args){String str ="abcd";System.out.println(str.isEmpty());}
运行结果如下:
版权归原作者 Lockey-s 所有, 如有侵权,请联系我们删除。