String类
关于Java JDK中内置的一个类:java.lang.String
String表示字符串类型,属于引用数据类型,不属于基本数据类型。
在java中随便使用双引号括起来的都是String对象。例如:"abc","hello","zhangsan",这是3个String对象。
java中规定,双引号括起来的字符串,是不可变的,也就是说"abc"自出生到最终死亡,不可变,不能变成"abcd",也不能变成"ab"。
在JDK当中,双引号括起来的字符串,例如:"abc" "def" 都是直接存储在方法区的字符串常量池当中的。
为什么SUN公司把字符串存储在一个“字符串常量池”当中呢。因为字符串在实际的开发中使用太频繁。为了执行效率,所以把字符串放到了方法区的字符串常量池当中。
凡是双引号括起来的都在字符串常量池中有一份。
String类中常用的构造方法
输出引用的时候,会自动调用toString()方法,默认Object的话,会自动输出对象的内存地址。
String类已经重写了toString()方法。
byte[] bytes = 数组;
byte[] bytes = {97,98,99};//97是a 98是b 99是c
String s2 = new String(bytes);
System.out.println(s2);//abc
String(字节数组,数组元素下标的起始位置,长度)
将byte数组的一部分转换成字符串。
byte[] bytes = {97,98,99};//97是a 98是b 99是c
String s3 = new String(bytes,1,2);
System.out.println(s3);//bc
将char数组全部转换成字符串
char[] chars = {'我','是','中','国','人'};
String s4 = new String(chars);
System.out.println(s4);//我是中国人
将char数组的一部分转换成字符串
char[] chars = {'我','是','中','国','人'};
String s5 = new String(chars,2,3);
System.out.println(s5);//中国人
直接用字面量的方式
String s1 = "abc";
System.out.println(s1);//abc
new对象的方式
String s6 = new String("hello world");
System.out.println(s6);
String类当中常用方法
1(掌握)、char charAt(int index)
返回 char指定索引处的值。
char c = "中国人".charAt(1);
System.out.println(c);//国
2(了解)、int compareTo(String anotherString)
按字典顺序比较两个字符串。
//字符串之间比较大小不能直接使用> < ,需要使用compareTo方法。
int result = "abc".compareTo("abc")
System.out.println(result);//0(等于0) 前后一致
int result = "abcd".compareTo("abce")
System.out.println(result);//-1(小于0) 前小后大
int result = "abce".compareTo("abcd")
System.out.println(result);//1(等于0) 前大后小
//拿着字符串第一个字母和后面字符串的第一个字母比较,能分出胜负就不再比较了。
System.out,println("xyz".compareTo("yxz"));//-1
3(掌握)、boolean contains(CharSequence s)
当且仅当此字符串包含指定的char值序列时才返回true。
//判断前面的字符串中是否包含后面的子字符串。
System.out.println("HellowWorld.java".contains(".java"));//true
System.out.println("http://www.baidu.com".contains("https://"));//false
4(掌握)、boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结尾。
//判断当前字符串是否以某个字符串结尾。
System.out.println("test.txt".endsWith(".java"));//false
System.out.println("test.txt".endsWith(".txt"));//true
System.out.println("shdahahgkhaghklahss".endsWith("ss"));//true
5(掌握)、boolean equals(Object anObject)
将此字符串与指定对象进行比较。
比较两个字符串必须使用equals方法,不能使用“==”。
equals方法有没有调用compareTo方法?老版本可以看一下。JDK13中并没有调用compareTo()方法。
equals只能看出相等不相等。
compareTo方法可以看出是否相等,并且同时还可以看出谁大谁小。
System.out.println("abc".equals("abc"));//true
6(掌握)、boolean equalsIgnoreCase(String anotherString)
将此 String与其他 String比较,忽略案例注意事项。
//判断两个字符串是否相等,并且同时忽略大小写。
System.out.println("ABc".equalsIgnoreCase("abc"));//true
7(掌握)、byte[] getBytes()
使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。
//将字符串对象转换成字节数组
byte[] bytes = "abcdef".getBytes();
for(int i = 0; i < bytes.length; i++){
System.out,println(bytes[i]);//97 98 99 100 101 102
}
8(掌握)、int indexof(String str)
返回指定子字符串第一次出现的字符串内的索引。
//判断某个子字符串在当前字符串中第一次出现处的索引(下标)。
System.out.println("oraclejavac++c#phppythonjavaoraclec++".indexOf("java"));//6
9(掌握)、boolean isEmpty()
返回true ,且仅当length()为0。
//判断某个字符串是否为“空字符串”。底层源代码调用的应该是字符串的length()方法。
String s = "";
System.out.println(s.isEmpty());//true
String s1 = "a";
System.out.println(s1.isEmpty());//false
10(掌握)、int length()
返回此字符串的长度
System.out.println("abc".length());//3
面试题:判断数组长度和判断字符串长度不一样
判断数组长度是length属性,判断字符串长度是length()方法。
11(掌握)、int lastIndexOf(String str)
返回指定字符的最后一次出现的字符串中的索引。
//判断某个子字符串在当前字符串中最后一次出现的索引(下标)。
System.out,println("oraclejavac++javac#phpjavapython".lastIndexOf("java"));//22
12(掌握)、String repalce(CharSequence target , CharSequence replacement)
将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。
//String的父接口就是:CharSequence
String newString = "http://www.baidu.com".replace("http://","https://");
System.out.println(newString); //https://www.baidu.com
13(掌握)、String [] split(String regex)
//拆分字符串
String[] ymd = "1980-10-11".split("-");//1980-10-11以-分隔符进行拆分。
for(int i = 0; i < ymd.length;i++){
System.out.println(ymd[i]);
}
14(掌握)、boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开头。
//判断某个字符串是否以某个子字符串开始。
System.out.println("http://www.baidu.com".startsWith("http"));//true
System.out.println("http://www.baidu.com".startsWith("https"));//false
15(掌握)、String substring(int beginIndex)
参数是起始下标
//截取字符串
System.out.println("http://www.baidu.com".substring(7));//www.baidu.com
16(掌握)、String substring(int beginIndex, int endIndex)
参数是起始下标和结束下标
截取的字符串,包含起始下标但不包含结束下标
beginIndex起始位置(包括)
endIndex结束位置(不包括)
System.out.println("http://www.baidu.com".substring(7,10));//www
17(掌握)、char[] toCharArray()
将此字符串转换为新的字符数组。
//将字符串转换成char数组
charr[] chars = "我是中国人".toCharArray();
for(int i = 0; i < chars.length; i++){
System.out.println(chars[i]);
}
18(掌握)、String toLowerCase()
//转换为小写
System.out.println("ABCdefVCKEYz".toLowerCase());
19(掌握)、String toUpperCase()
//转换为大写
System.out.println("ABCdefVCKEYz".toUpperCase());
20(掌握)、String trim();
//去除字符串前后空白
System.out.println(" hello world ".trim());//hello world
21(掌握)、String中只有一个方法是静态的,不需要new对象
这个方法叫valueOf
作用:将非字符串转换成字符串
//String s1 = String.valueOf(true);
//String s1 = String.valueOf(100);
String s1 = String.valueOf(3.14);
System.out.println(s1);
这个静态的valueOf()方法,参数是一个对象的时候,会自动调用该对象的toString()方法。
StringBuffer
我们在实际的开发中,如果需要进行字符串的频繁拼接,会有什么问题?
因为java中的字符串是不可变的,每一次拼接都会产生新字符串。
这样会占用大量的方法去内存。造成内存空间的浪费。
String s = "abc";
s += "hello";
就以上两行代码,就导致在方法去字符串常量池中创建了3个对象。
"abc"
"hello"
"abchello"
如果以后需要进行大量字符串的拼接操作,建议使用JDK中自带的:
java.lang.StringBuffer
java.lang.StringBuilder
如何优化StringBuffer的性能?
在创建StringBuffer的时候尽可能给定一个初始化容量。
最好减少底层数组的扩容次数。预估计以下,给一个大一些的初始化容量。
关键点:给一个合适的初始化容量。可以提高程序的执行效率。
public class Test {
public static void main(String[] args) {
//创建一个初始化容量为16个byte[]数组。(字符串缓冲区对象)
StringBuffer stringBuffer = new StringBuffer();
//拼接字符串,以后拼接字符串统一调用append()方法。
//append是追加的意思。
stringBuffer.append("a");
stringBuffer.append("b");
stringBuffer.append("c");
stringBuffer.append(true);
stringBuffer.append(3.14);
//append方法在底层进行追加的时候,如果byte数组满了,会自动扩容。
stringBuffer.append(100L);
//这里会自动调用toString方法
System.out.println(stringBuffer.toString());
//指定初始化容量的StringBuffer对象(字符串缓冲区对象)
StringBuffer sb = new StringBuffer(100);
sb.append("hello");
sb.append("world");
sb.append("hello");
sb.append("kitty");
System.out.println(sb);
}
}
StringBuffer和StringBuilder的区别:
StringBuffer中的方法都有synchronized关键字修饰。表示StringBuffer多线程环境下运行是安全的。
StringBuilder中的方法都没有synchronized关键字修饰,表示StringBuilder多线程环境下运行是不安全的。
StrtingBuffer是线程安全的。
StringBuilder是非线程安全的。