String
- 字符串是常量,创建之后不可改变
- 字符串字面值存储在字符串池中,可以共享
- String s = "hello"; 产生一个对象,字符串池中存储
- String s = new String("hello");//产生两个对象,堆、池各存储一个
String name = "hello";//"hello"常量存储在字符常量池中。name在栈区指向方法区字符串常量池“hello”
name = "zhangsan";//把zhangsan赋值给name,并不是把hello修改称zhangsan;而是在字符串池创建zhangsan
//不可变性:给字符串赋值时,并没有修改数据,而是重新开辟空间
String name2 = "zhangsan";//栈区中的name2指向方法区中字符串常量池的“zhangsan”
//这样name;name2指向字符串池里的同一个对象“zhangsan”
//name;name2在栈区是两个地址
//字符串另一种创建方式
String str = new String("java");
//str在栈区,“java”在方法区字符串池, new String--->堆中创建一个对象“java”
//str指向堆中的对象,,存的是堆中的“java”的地址
//但是实际上内存里,堆中的“java”是指向常量池中的“java”,堆中没有“java”(可以理解有);但实际也是有两个对(堆中和常量池)
String str2 = new String("java");
System.out.println(str == str2);//false
System.out.println(str.equals(str2));//true(因为String类重写了equals方法,比较的是内容了)
内存分析
常用方法
- length(); 返回字符串长度
- charAt(int index); 返回某个位置的字符
- contains(String str); 判断是否包含某个字符串
- toCharArray(); 将字符串转换成数组
- indexOf(String str); 查找str首次出现的下标,存在,则返回该下标;不存在则返回-1
- lastIndexOf(String str); 查找字符串在当前字符串中最后一次出现的下标索引
- trim(); 去掉字符串前后的空格
- toUpperCase(); 将小写转成大写
- endWith(String str); 判断字符串是否以str结尾
- replace(char oldChar,char newChar); 将旧字符(或字符串)替换成新字符串
- split(String str); 根据str做拆分
- equals();比较字符串是否相等
- compare(); 比较大小(字典表顺序)
//字符串方法使用
String content = "java2024";
System.out.println(content.length());//8
System.out.println(content.charAt(content.length()-1));//4
System.out.println(content.contains("java"));//true
System.out.println(Arrays.toString(content.toCharArray()));//[j, a, v, a, 2, 0, 2, 4]
System.out.println(content.indexOf("java"));//0
System.out.println(content.lastIndexOf("2"));//6
String content2 = " hello world ";
System.out.println(content2.trim());//hello world
System.out.println(content2.toUpperCase());// HELLO WORLD (content2还是指向" hello world ")
System.out.println(content2.toLowerCase());// hello world
System.out.println(content2.endsWith(" "));//true
System.out.println(content2.startsWith("hello"));//false
System.out.println(content.replace("java", "php"));//php2024
String[] arr = content2.split(" +");//填个加号表示多个空格也拆分
for (String s : arr) {
System.out.println(s);
}
/*
hello
world
*/
案例
-
需求
已知String str = ”this is a text“;
- 将str的单词单独获取出来
- 将str中text替换为practice
- 在text前面插入一个easy
- 将每个单词的首字母改成大写
String str = "this is a text";
//1
String[] arr = str.split(" ");
for (String s : arr) {
System.out.println(s);
}
//2
System.out.println(str.replace("text", "practice"));
//3
System.out.println(str.replace("text", "easy text"));
//4
for (int i = 0; i < arr.length; i++) {
char first = arr[i].charAt(0);
//把第一个字符变大写
char upperfirst = Character.toUpperCase(first);//Character 是char的包装类
String news = upperfirst+arr[i].substring(1);//substring();截取
System.out.println(news);
}
/*
this
is
a
text
this is a practice
this is a easy text
This
Is
A
Text
*/
可变字符串
- 由于String类的不可变性,运行过程中会产生很多无用字符串,效率上来讲也比较低。
StringBuffer
- 可变长字符串,JDK1.0提供,运行效率慢(比String高的),线程安全
StringBuffer sb = new StringBuffer();
//1 append(); 追加
sb.append("javaYes");
System.out.println(sb.toString());//javaYes
sb.append("javaNo");
System.out.println(sb.toString());//javaYesjavaNo
//2 insert(); 添加
sb.insert(0,"我在最前面");
System.out.println(sb.toString());//我在最前面javaYesjavaNo
//3 replace();
sb.replace(0,5,"hello");//hellojavaYesjavaNo
System.out.println(sb.toString());
//4 delete();删除
sb.delete(0,5);
System.out.println(sb.toString());//javaYesjavaNo
//若要清空,则delete(0,sb.lenth());
StringBuilder
-
可变长字符串,JDK5.0提供,运行效率块,线程不安全
-
用法与StringBuffer一样,在单线程情况下就用StringBuilder