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);//falseSystem.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());//8System.out.println(content.charAt(content.length()-1));//4System.out.println(content.contains("java"));//trueSystem.out.println(Arrays.toString(content.toCharArray()));//[j, a, v, a, 2, 0, 2, 4]System.out.println(content.indexOf("java"));//0System.out.println(content.lastIndexOf("2"));//6String content2 = " hello world ";System.out.println(content2.trim());//hello worldSystem.out.println(content2.toUpperCase());// HELLO WORLD (content2还是指向" hello world ")System.out.println(content2.toLowerCase());// hello worldSystem.out.println(content2.endsWith(" "));//trueSystem.out.println(content2.startsWith("hello"));//falseSystem.out.println(content.replace("java", "php"));//php2024String[] arr = content2.split(" +");//填个加号表示多个空格也拆分for (String s : arr) {System.out.println(s);}/*helloworld*/
案例
-
需求
已知String str = ”this is a text“;
- 将str的单词单独获取出来
- 将str中text替换为practice
- 在text前面插入一个easy
- 将每个单词的首字母改成大写
String str = "this is a text";//1String[] arr = str.split(" ");for (String s : arr) {System.out.println(s);}//2System.out.println(str.replace("text", "practice"));//3System.out.println(str.replace("text", "easy text"));//4for (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);}/*thisisatextthis is a practicethis is a easy textThisIsAText*/
可变字符串
- 由于String类的不可变性,运行过程中会产生很多无用字符串,效率上来讲也比较低。
StringBuffer
- 可变长字符串,JDK1.0提供,运行效率慢(比String高的),线程安全
StringBuffer sb = new StringBuffer();//1 append(); 追加sb.append("javaYes");System.out.println(sb.toString());//javaYessb.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");//hellojavaYesjavaNoSystem.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