字符串是常量,创建后是不可改变的。
字符串的字面值是存储在字符串池中的,可以共享(字符串池是在方法区内)
当我们创建一个新的字符串变量的时候,系统会现在字符串里找是否有这个字符串有的话就会直接指向这里,没有的话就会重新创建
例:
首先我们赋值一个字符串变量然后 再修改它赋值的变量 再用hashCode()方法打印出地址的编码来看一下是否是一个值。
package TestString;
public class Demo1 {
public static void main(String[] args){
String name = "张三";
System.out.println(name.hashCode());
name = "hello";
System.out.println(name.hashCode());
}
}
运行结果:
并不是一个地址!为什么一个字符串变量中间修改运行所赋的值地址就不一样了呢?这是因为我们第一次所赋的值在字符串池中开辟后就一直存在,当我们修改这个变量的值的时候又再字符串池中开辟了新的空间储存值 ,然后指向这个新的值。
这个是我们第一次赋值时的变化:
当我们第二次赋值的时候的状态:指向地址就变了
我们再测试一下:
package TestString;
public class Demo1 {
public static void main(String[] args){
String name = "张三";
System.out.println(name.hashCode());
name = "hello";
System.out.println(name.hashCode());
//我们再测试一下
String name2 = "张三";
System.out.println(name2.hashCode());
}
}
运行结果:地址一样
除了上面的那种直接赋值,String类型也可以通过构造器进行赋值(new),通过构造器的话就会产生两个对象一个是在堆中一个是在池中,但是堆中的那个也是指向池中的,只不过是有了中间商一样的感觉。(在运行的时候一般会直接指向了池中)
//演示字符串的另一种创建方式
String str = new String("王五爱学习编程其中最喜欢Java");
String str2 = new String("王五爱学习编程其中最喜欢Java");
System.out.println(str == str2);
运行结果:
常用方法:
方法一:
public int lenght():返回字符串长度
方法二:
public char charAt(int index):根据下标获取对应的字符
方法三:
public boolean contains(String str):判断当前字符串中是否包含str。
方法四:
public char[] toCharArray():将字符串转换成数组
方法五:
public int indexOf(String str):查找str首次出现的下标,存在返回该下标,不存在返回-1..。
方法六:
public int lastIndexOf(String str):查找子字符串,在字符串中最后一次出现的下标。
方法七:
public String trim():去掉字符串前后的空格。
方法八:
public String toUpperCase():将小写转换为大写
public String toLowerCase():将大写转换为小写
方法九:
public boolean endsWith (String str):判断字符串是不是以str结尾。
public boolean startsWith(String str):判断是否是以str开头。
方法十:
public String replace(Char oldChar,Char newChar):将旧的字符串替换成新的字符串。
方法十一:
public String[] split(String str):根据str做拆分
代码演示:
package TestString;
import java.util.Arrays;
public class Demo2 {
public static void main(String[] args){
String name = " 王五爱学习编程其中最喜欢Java ";
//字符串类型常用方法
//1.public int length()返回字符串长度
System.out.println(name.length());
//2.public char charAt(int index):根据下标获取对应的字符
System.out.println(name.charAt(3));
//3.public boolean contains(String str):判断当前字符串中是否包含str
System.out.println(name.contains("Java"));
//4.public char[] toCharArray()将字符串转换为数组
System.out.println(Arrays.toString(name.toCharArray()));
//5.public int indexOf(String str):查找str在字符串中首次出现的下标,存在返回下标,不存在返回-1
System.out.println(name.indexOf("学"));
//6.public int lastIndexOf(string str):查找子字符串在字符串中最后一次出现的下标
System.out.println(name.lastIndexOf("Java"));
//7.public String trim():去掉字符串前后的空格
System.out.println(name.trim());
/*8.public String toUpperCase():将小写转换为大写
public String toLowerCase():将大写转换为小写
*/
System.out.println(name.toUpperCase());
System.out.println(name.toLowerCase());
//9.public String endsWith(String str):判断字符串是否是以str结尾
System.out.println(name.endsWith("Java "));
System.out.println(name.startsWith("Java"));
/*10.public String replace(Char oldChar,Char newChar)
将旧的字符串替换成新的字符串
*/
System.out.println(name.replace("王五","赵六"));
//11.public String[] split(String str):根据str做拆分
String name1 = " 1 2 3 4 5 6 7 8!9";
System.out.println(name1);
/*用空格替换,当想用两个替换条件的时候可以用[ !]中括号框起来两个条件
想要替换的地方空格有连续多个可以在[ !]外加个加号[ !]+;
*/
System.out.println(Arrays.toString(name1.split("[ !]")));
}
}
运行结果:
案例演示:
需求:
已知 String str = "this is a text"
1.将str中的单词单独获取出来
2.将str中的text替换成 practice。
3.在text前插入一个easy。
4.将每个单词的首字母变为大小。
代码演示:
package TestString;
/*
案例演示:
需求:
已知 String str = "this is a text"
1.将str中的单词单独获取出来
2.将str中的test替换成practice
3.在text前面插入一个easy
4.将每个单词的首字母变为大写
*/
public class Demo03 {
public static void main(String[] args){
String str = "this is a text";
//1.将str中的单词单独获取出来
String[] arr = str.split(" ");
//1.2遍历一下数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("---------------------");
//2.将str中的test替换为practice
System.out.println(str.replace(" text"," practice"));
System.out.println("---------------------");
//3.在text前插入一个easy,可以用替换的思路去完成
System.out.println(str.replace(" text"," easy text"));
System.out.println("---------------------");
//4.将每个单词的首字母变为大小
for (int i = 0; i < arr.length; i++) {
//获取首字母的下标赋值给c
char c = arr[i].charAt(0);
//通过char的包装类将第一个字符变成大写的
char b = Character.toUpperCase(c);
//通过substring()方法拼接起来赋值给新的字符串
//substring()方法获取x--x位的字符
String str2 = b+arr[i].substring(1);
System.out.println(str2);
}
}
}
运行结果:
可变字符串:及常用方法
StringBuffer类:可变长字符串,由JDK1.0提供,运行效率慢,线程安全
StringBuilder类:可变长字符串,由JDK5.0提供,运行效率块,线程不安全
常用方法演示代码:
package TestString;
/**
* StringBuffer和StringBuilder的使用
* 和String的区别
* 1.效率要比String效率高
* 2.比String节省内存
*/
public class TestStringBufferOrStringBuilder {
public static void main(String[] args){
StringBuffer sb = new StringBuffer();
//1.append()方法:效果是追加
sb.append("java真香");
System.out.println(sb.toString());
sb.append("java yyds");
System.out.println(sb.toString());
System.out.println("======================");
//2.insert()方法:效果插入也可以说是添加
sb.insert(0,"张三喜欢java,");
System.out.println(sb);
System.out.println("======================");
//3.replace()方法:替换这里的替换方法比String类的好的是可以指定位置
sb.replace(8,15,"java真好玩呀!~");//含头不含尾
System.out.println(sb);
System.out.println("======================");
//4.delete()方法:效果删除,可以指定位置
sb.delete(0,2);
System.out.println(sb);
System.out.println("======================");
//5.reverse()方法:效果反转
sb.reverse();
System.out.println(sb);
}
}
运行结果:
效率运行测试代码:
String类型测试效果:
package TestString;
//StingBuffer和StringBuilder效率运行演示
public class Demo4 {
public static void main(String[] args){
//获取开始时间
long start = System.currentTimeMillis();
String str = "";
for (int i = 0; i < 9999; i++) {
str+=i;//拼接字符串
}
System.out.println(str);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));
}
}
结果:
StringBuilder测试:
package TestString;
//StingBuffer和StringBuilder效率运行演示
public class Demo4 {
public static void main(String[] args){
//获取开始时间
long start = System.currentTimeMillis();
//使用StringBuilder运行一下
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 9999; i++) {
sb.append(i);
}
System.out.println(sb.toString());
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));
}
}
运行结果:
StringBuffer测试:
package TestString;
//StingBuffer和StringBuilder效率运行演示
public class Demo4 {
public static void main(String[] args){
//获取开始时间
long start = System.currentTimeMillis();
//使用StringBuilder运行一下
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 9999; i++) {
sb.append(i);
}
System.out.println(sb.toString());
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));
}
}
运行结果: