在Java中,String是一个引用类型,它本身也是一个class。
但是,Java编译器对String有特殊处理,即可以直接使用"..."来表示一个字符串。
String s = “Hello”
实际上字符串在String内部是通过一个char[]数组表示的,因此,按下面的写法也是可以的:
String s2 = new String(new char[] {‘H‘,‘e‘,‘l‘,‘l‘,‘o‘})
因为String太常用了,所以Java提供了“...”这种字符字面量表示方法。
Java字符串的一个重要特点就是字符串不可变。
这种不可变性是通过内部的private final char[]字段,以及没有任何修改char[]的方法实现的。
public class catchExample2 { public static void main(String[] args) { String s = "Hello"; System.out.println(s); //Hello s = s.toUpperCase(); System.out.println(s); //HELLO } }
上面的示例并不能说明字符串内容是可变的,这里是创建了一个新的字符串。
1.字符串比较
当我们想要比较两个字符串是否相同时,必须使用equals()方法而不能用==。
引用类型必须使用equals,enum除外。
public class catchExample2 { public static void main(String[] args) { String s1 = "hello"; String s2 = "hello"; System.out.println(s1 == s2); //true System.out.println(s1.equals(s2)); //true } }
表面上看==与equals是完全等价的。
如果我们更换一种写法,可能结果就会完全不同了。
public class catchExample2 { public static void main(String[] args) { String s1 = "hello"; String s2 = "HEllo".toLowerCase(); System.out.println(s1 == s2); //false System.out.println(s1.equals(s2)); //true } }
Java编译器在编译期间会自动把所有相同的字符串当作一个对象放入常量池,
equals只需要判断字符串的内容是否一致,而==其实判断是内存地址。
“hello”和"HEllo"其实代表了不同的字符串,所以内存地址肯定不一样。
如果要忽略大小写比较,可以使用equalsIgnoreCase()方法。
String类还提供了多种方法来搜索子串、提取子串。常用的方法有:
//是否包含某个子串: "hello".contains("ll") //注意到contains()方法的参数是CharSequence而不是String,因为CharSequence是String的父类。 //某个子串第一次出现的位置: "hello".indexOf("l"); //2 //某个子串最后一次出现的位置: "hello".lastIndexOf("l"); //3 //是否以某个子串开头: "hello".startsWith("he"); //true //是否以某个子串结尾: "hello".endsWith("lo"); //true //切片,与python不同,单个数字并不是代表取一个值,而是取后面所有的值。 "hello".substring(2); //llo "hello".substring(2,4); //ll
2.去除首尾空白字符
使用trim()方法可以移除字符串首尾空白字符。空白字符包括空格,\t,\r,\n
" \tHello\r\n ".trim() //Hello
注意:trim()并没有改变字符串的内容,而是返回一个新的字符串。
另一个strip()方法也可以移除字符串首尾空白字符。
它和trim()不同的是,类似中文的空格字符\u3000也会被移除。
String还提供了isEmpty()和isBlank()来判断字符串是否为空和空白字符串。
3.替换子串
要在字符串中替换子串,有两种方法。一种是根据字符或者字符串替换。
String s = “hello”;
s.replace(‘l‘, ‘w’);
另一种是通过正则表达式替换:
String s = “A,,B;C,D”
s.replaceALL("[\\,\\:\\s]+", ",")
4.分割字符串
要分割字符串,使用split()方法,并且传入的也是正则表达式:
String s = “A,B,C,D”; String[] ss = s.plit("\\,"); //{"A","B","C","D"}
5.拼接字符串
拼接字符串使用静态方法join(),它用指定的字符串连接字符串数组:
String[] arr = {"A", "B", "C"} String s = String.join("***", arr); //"A***B***C"
6.类型转换
要把任意基本类型或引用类型转换为字符串,可以使用静态方法valueof()。
这是一个重载方法,编译器会根据参数自动选择合适的方法:
String.valueOf(123); // "123" String.valueOf(45.67); // "45.67" String.valueOf(true); // "true" String.valueOf(new Object()); // 类似java.lang.Object@636be97c
要把字符串转换为其他类型,就需要根据情况。
int n1 = Integer.parseInt("123"); // 123 int n2 = Integer.parseInt("ff", 16); // 按十六进制转换,255
把字符串转换为boolean类型:
boolean b1 = Boolean.parseBoolean("true"); // true boolean b2 = Boolean.parseBoolean("FALSE"); // false
要特别注意,Integer有个getInteger(Sting)方法,它不是将字符串转换为int,
而是把字符串对应的系统变量转换为Integer:
Integer.getInteger(”java.version“);
转换为char[]
String和char[]类型可以转换,方法是:
char[] cs = “Hello”.toCharArray(); String s = new String(cs)
如果修改了char[]数组,String并不会改变:
public class catchExample2 { public static void main(String[] args) { char[] cs = "Hello".toCharArray(); String s = new String(cs); System.out.println(s); //Hello cs[0] = ‘X‘; System.out.println(s); //Hello } }
这是因为通过new String(char[])创建新的String实例时,它并不会直接引用传入的char[]数组,
所以,修改外部的char[]数组不会影响String实例内部的char[]数组,因为这是两个不同的数组。
package com.imooc.iexecption; import java.util.Arrays; class Score { private int[] scores; public Score(int[] scores) { this.scores = scores; } public void printScores() { System.out.println(Arrays.toString(scores)); } } public class catchExample2 { public static void main(String[] args) { int[] scores = new int[] {88, 77, 51, 66}; Score s = new Score(scores); s.printScores(); scores[2] = 99; s.printScores(); } }
我们发现两次的输出都不一样,由于score内部直接引用了外部传入的int[]数组,
这会造成外部代码对int[]数组的修改。
原文:https://www.cnblogs.com/yangmingxianshen/p/12501237.html