字符串
1.简介
在Java类库中提供了一个类叫做String,每个用双引号引起来的字符串都是这个类的一个实例。如:String a=“abc”;
2.构造方法
- public String():无参构造
- public String(byte[] bytes):将字节数组转为默认编码格式的字符串,中文默认为GBK
- public String(byte[] bytes, Charset charset):将字节数组转为charset格式的字符串,charset是一种编码格式
- public String(byte[] bytes,int offset,int length):将字节数组offset位置开始,长度为length的部分转为字符串
- public String(char[] value):将字符数组转为字符串
- public String(char[] value,int offset,int count):将字符数组offset位置开始,长度为count的部分转为字符串
3.特点
①字符串直接赋值(如,String s=“abc”;)是先到方法区中字符串常量池里面去找,如果有就直接返回,没有就创建并返回。
②一旦赋值就不能被改变,这里指的是内容不能被改变,而地址值可以改变。例,
String s="hello"; //在字符串常量池中创建"hello",并将它的地址给s
s+="world"; //在字符串常量池中创建"world",创建新的内存将"hello"和"world"放入新内存,并将新内存地址给s
System.out.println(s);
③通过new创建的字符串对象它会在堆中开辟一片内存空间,但它仍然将字符串值创建在字符串常量池中,并将池中该字符串的地址(如,0X001)返回给堆中的内存空间,然后将堆的内存地址(如,0X0001)给对象。
注:此处的两个地址并不相同。
举例:String s=new String(" hello ")和String s="hello"有区别吗?
④String类已重写equals方法,例,
String s = "hello";
String s1=new String("hello");
System.out.println(s==s1); //false
System.out.println(s.equals(s1)); //true
String s2="hello";
System.out.println(s==s2); //true
System.out.println(s.equals(s2)); //true
⑤两个字符串变量相加是先开辟内存,再拼接,两个字符串常量相加是先拼接看常量池中有没有这个值,有就将该内存地址返回给结果,没有就重新开辟一片内存。例,
String s="hello";
String s1="world";
String s2="helloworld";
String s3="hello world";
System.out.println(s2==s1+s); //false
System.out.println(s2=="hello"+"world"); //true
System.out.println(s3=="hello"+"world"); //false
注:字符串中带空格的区别
⑥字符串在底层会自动转为字符数组
4.常用方法
①获取字符串的长度
public int length()
获取指定索引位置的字符
public char charAt(int index)
String s="udngndn";
System.out.println(s.length()); //7
System.out.println(s.charAt(5)); //d
charAt方法的底层是将字符串转为char[],所以下标从0开始
②子串
String类的substring方法可以从一个较大的字符串中提取出一个子串。
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
String a="123456";
String b=a.substring(1,4); //b="234"
前一个数字是开始提取的位置,后一个数字是截止提取的位置(不包括此位置)。
③拼接
在Java中使用‘+’来拼接两个字符串,或public String concat(String str)
String a="1234";
String b="56789";
String c=a+b; //c="123456789"
"Hello".concat("World") //HelloWorld
当一个字符串与一个非字符串进行拼接时,非字符串将被转为字符串。
String a="你好";
int b=3;
int c=4;
String d=a+b; //d="你好3"
String e=b+c+a; //e="7你好"
String f=a+b+c; //f="你好34"
System.out.println("b的值是:"+b); //字符串拼接的应用
注:运算符的优先级
如果要把多个字符串用一个符号分割可以用静态join()方法:
String a=String.join("*", "123","456"); //a="123*456"
④字符串修改
String类中没有提供用于修改字符串的方法,因此将String类的对象称为不可变的字符串,但它的优点就是字符串可以共享。
可以通过下面两种方法来间接修改字符串:
字符串的拼接
修改变量,让它引用另一个字符串
String a="123";
String b="12";
a=b; //a="12"
⑤判断字符串是否相等
public boolean equals(Object anObject)
用equals方法判断两个字符串的内容是否相等(可以是字符串变量,也可以是值)。
a.equals(b);
"123".equals("12");
public boolean equalsIgnoreCase(String anotherString)
如果不区分大小写用equalsIgnoreCase()方法。
"A".equalsIgnoreCase("a") //true
不能使用==来检测两个字符串是否相等,因为它只会检测两个字符串的地址值是否一样。
String a=new String("123");
String b=new String("123");
boolean c=(a==b); //c=false
⑥判断字符串是否为空
public boolean isEmpty()
判断字符串长度是否为0,是返回true,否返回false
空串""是长度为0的字符串。null是String变量的一个特殊值,如果用此变量调用方法会出现错误。
空串与null不一样。将null赋值给String类型的变量则此变量不指向内存中的任何位置,等价于没有对象,则不能调用方法,一旦调用方法会出现NullPointerException。
String s="udngndn";
String s2="";
String s3=null;
System.out.println(s.isEmpty()); //false
System.out.println(s2.isEmpty()); //true
System.out.println(s3.isEmpty()); //Exception in thread "main" java.lang.NullPointerException
⑦判断字符串中是否包含指定内容
public boolean contains(CharSequence s)
判断字符串中是否包含s,若s为字符串中连续的一部分返回true,否则返回false
String s="udngndn";
System.out.println(s.contains("ng")); //true
System.out.println(s.contains("nn")); //false
⑧判断字符串是否以给定的字符串开头或结尾
public boolean startsWith(String prefix)
public boolean endsWith(String suffix)
String s="udngndn";
System.out.println(s.startsWith("u")); //true
System.out.println(s.startsWith("udn")); //true
System.out.println(s.endsWith("n")); //true
System.out.println(s.endsWith("gndn")); //true
⑨寻找指定字符或字符串的索引
public int indexOf(int ch) //返回指定字符在字符串中出现的第一次的位置索引
public int indexOf(int ch,int fromIndex) //返回指定字符在字符串fromIndex位置后出现的第一次的位置索引
public int indexOf(String str)
public int indexOf(String str,int fromIndex)
前两个参数为int的原因:数字也能表示一个字符,int参数可以隐式转换为字符,所以可以直接给参数一个字符值,但如果参数为char,此时给参数一个int值就是显示转换了,会出现精度损失。
String s="udngndn";
System.out.println(s.indexOf('n')); //2
System.out.println(s.indexOf(110)); //2
System.out.println(s.indexOf('d', 2)); //5
System.out.println(s.indexOf("dn")); //1
System.out.println(s.indexOf("dg")); //-1,找不到返回-1
System.out.println(s.indexOf("dn",5)); //5,搜索位置包括第二个参数
System.out.println(s.indexOf('d', 40)); //-1
⑩转换
把字符串转换为字节数组,此时的编码格式为系统默认的编码格式,中文默认为GBK
public byte[] getBytes()
public byte[] getBytes(Charset charset)
把字符串转换为charset格式的字节数组,charset是一种编码格式
String s="udngndn";
byte[] b = s.getBytes();
System.out.println(Arrays.toString(b)); //[117, 100, 110, 103, 110, 100, 110]
String s="哈哈";
byte[] bb = s.getBytes();
byte[] b = s.getBytes("utf-8");
System.out.println(Arrays.toString(b)); //[117, 100, 110, 103, 110, 100, 110]
System.out.println(Arrays.toString(bb)); //[-71, -2, -71, -2]
把字符串转换为字符数组
public char[] toCharArray()
String s="udngndn";
char[] c = s.toCharArray();
System.out.println(Arrays.toString(c)); //[u, d, n, g, n, d, n]
把字符数组转为字符串,静态
public static String valueOf(char[] data)
String s="udngndn";
char[] c = s.toCharArray();
System.out.println(String.valueOf(c)); //udngndn
把int值转为字符串,静态
public static String valueOf(int i)
将任意类型数据转为字符串,静态
public static String valueOf(Object obj)
将字符串转为小写、大写
public String toLowerCase()
public String toUpperCase()
String s="uDnGNdn";
System.out.println(s.toLowerCase()); //udngndn 产生一个新字符串
System.out.println(s); //uDnGNdn s本身并无变化
System.out.println(s.toUpperCase()); //UDNGNDN
5.其他方法
①将字符或字符串替换
public String replace(char oldChar,char newChar)
public String replace(CharSequence target,CharSequence replacement)
String s="uDnGNdn";
System.out.println(s.replace('n', 'k')); //uDkGNdk
System.out.println(s.replace("nGN", "haha")); //uDhahadn
②去除字符串两端空格
public String trim()
String s=" uD nG Ndn ";
System.out.println(s.trim()); //uD nG Ndn
System.out.println(s); // uD nG Ndn ,字符串本身没有改变
③排序
public int compareTo(String anotherString)
public int compareToIgnoreCase(String str)
比较结果为两个字符串ASCII值相减,但相减的只是长度最小的那部分,超出的那部分并不相减,此处可以看源码
String s="uDnGNdn";
System.out.println(s.compareTo("gdc")); //14
6.易错点
①传值问题
String是一种特殊的引用数据类型,它的值等价于常量,它在方法中并不传地址值而传的是数据值。例,
public static void change(String s, String s2) {
s = s2;
s2 = s + s2;
}
public static void main(String[] args) {
String s = new String("haha");
String s2 = new String("hahahah1");
change(s, s2);
System.out.println(s + " " + s2); //haha hahahah1
}
7.StringBuffer类
详细介绍请看:Java输入输出流与文件