在学习String类之前,先看一道笔试题:new String("abc")创建了几个对象?
答案: 两个对象, 一个对象是 位于字符串常量池中,一个对象是位于堆内存中。
原因:主要取决于字符串的创建方式;
String str = “hello”这种方式创建字符串的时候,jvm首先检查字符串常量池中是否存在该字符串对象,如果存在,就不会在字符串常量池中在创建了,直接返回该字符串在字符串常量池中的内存地址。如果该字符串不存在在字符串常量池中,就会在字符串常量池中先创建该字符串的对象,然后在返回。
new String("hello");这种方式创建字符串对象的时候,jvm首先会先检查字符串常量翅中是否存在该字符串,如果存在,则不会在字符串常量池中创建了,如果不存在就会在字符串常量池中创建该字符串对象,然后还会在堆内存中在创建一份字符串的对象,把字符串常量池中的字符串内容拷贝到堆内存中的字符串对象,然后返回堆内存中字符串对象的内存地址。
代码验证如下:
1 public class StringDemo { 2 3 public static void main(String[] args) { 4 String str1 = "hello world"; 5 String str2 = "hello world"; 6 String str3 = new String("hello world"); 7 String str4 = new String("hello world"); 8 System.out.println("str1==str2?"+(str1==str2));//true 9 System.out.println("str2==str3?"+(str2==str3));//false 10 System.out.println("str3==str4?"+(str3==str4));//false 11 System.out.println("str3 equals str4?"+str3.equals(str4));//true 12 } 13 14 }
String类中常用的方法:
1、构造方法
String() 创建一个空内容 的字符串对象。
String(byte[] bytes) 使用一个字节数组构建一个字符串对象
String(byte[] bytes, int offset, int length)
bytes : 要解码的数组
offset: 指定从数组中那个索引值开始解码。
length: 要解码多个元素。
String(char[] value) 使用一个字符数组构建一个字符串。
String(char[] value, int offset, int count) 使用一个字符数组构建一个字符串, 指定开始的索引值,与使用字符个数。
String(int[] codePoints,int offset,int count) 类似用String(byte[] bytes, int offset, int length)
String(String original)
代码示例:
1 public class Demo2 { 2 3 public static void main(String[] args) { 4 String str = new String(); 5 byte[] buf = {97,98,99}; 6 7 str = new String(buf); //使用一个字节数组构建一个字符串对象 8 str = new String(buf,1,2); //使用一个字节数组构建一个字符串对象,指定开始解码 的索引值和解码的个数。 9 10 char[] arr = {'明','天','是','圣','诞'}; 11 str = new String(arr); //使用字符数组构建一个字符串 12 str = new String(arr,3,2); 13 14 int[] buf2 = {65,66,67}; 15 str = new String(buf2,0,3); 16 17 str = new String("abc"); 18 19 System.out.println("字符串的内容:"+str); 20 } 21 }
2、获取方法
int length() 获取字符串的长度
char charAt(int index) 获取特定位置的字符 (角标越界)
int indexOf(String str) 查找子串第一次出现的索引值,如果子串没有出现 在字符串中,那么则返回-1表示。
int lastIndexOf(String str) 查找子串最后一次出现的索引值 , 如果子串没有出现 在字符串中,那么则返回-1表示
代码示例:
1 public class Demo3 { 2 3 public static void main(String[] args) { 4 String str = "abc中国ab中国"; 5 System.out.println("字符串的字符 个数: " + str.length() ); 6 System.out.println("根据索引值获取对应 的字符:"+ str.charAt(3)); 7 System.out.println("查找子串第一次出现的索引值:" + str.indexOf("中国")); 8 System.out.println("查找子串最后一次出现的索引值:" + str.lastIndexOf("中国")); 9 } 10 11 12 }
3、判断方法
boolean endsWith(String str) 是否以指定字符结束
boolean isEmpty()是否长度为0 如:“” null V1.6
boolean contains(CharSequences) 是否包含指定序列 应用:搜索 CharSequences可以理解为String
boolean equals(Object anObject) 是否相等
boolean equalsIgnoreCase(String anotherString) 忽略大小写是否相等
代码示例如下:
1 public class Demo4 { 2 3 public static void main(String[] args) { 4 String str = "Demo.java"; 5 System.out.println("是否以指定 的字符串结束:"+ str.endsWith("ja")); 6 //str = ""; 7 System.out.println("判断字符串是否为空内容:"+str.isEmpty()); 8 System.out.println("判断字符串是否包含指定的内容:"+ str.contains("Demo")); 9 System.out.println("判断两个 字符串的内容是否一致:"+ "DEMO.JAVA".equals(str)); 10 System.out.println("判断两个字符串的内容是否一致(忽略大小写比较):"+ "DEMO.JAVA".equalsIgnoreCase(str)); 11 12 } 13 14 }
4、转换方法
char[] toCharArray() 将字符串转换为字符数组
byte[] getBytes();
代码示例:
1 public class Demo5 { 2 3 //转换的方法 4 char[] buf = str.toCharArray(); //把字符串转换字符数组 5 System.out.println("字符数组:"+ Arrays.toString(buf)); 6 byte[] buf2 = str.getBytes(); //把字符串转字节数组 7 System.out.println("字节数组:"+ Arrays.toString(buf2)); 8 } 9 10 }
5、其他方法
String replace(String oldChar, String newChar) 替换
String[] split(String regex) 切割
String substring(int beginIndex) 指定开始 的索引值截取子串
String substring(int beginIndex, int endIndex)指定开始 与结束的索引值截取子串
String toUpperCase() 转大写
String toLowerCase() 转小写
String trim() 去除字符串首尾的空格
代码示例如下:
1 public class Demo5 { 2 3 public static void main(String[] args) { 4 String str = "今天晚上不考试"; 5 System.out.println("指定新内容替换旧 的内容:"+ str.replace("不", "要好好")); 6 str = "大家-下-午-好"; 7 String[] arr = str.split("-"); //根据指定的字符进行切割 。 8 System.out.println("字符串数组的内容:"+ Arrays.toString(arr)); 9 str = "好好学习天天向上"; 10 System.out.println("指定开始的索引值截取子串:"+ str.substring(2)); 11 System.out.println("指定开始的索引值截取子串:"+ str.substring(2,6)); //包头不包尾 注意:截取的内容是包括开始的索引值,不包括结束的索引值, 截取的位置是结束的索引值-1. 12 13 str = "abC中国"; 14 System.out.println("转大写:" + str.toUpperCase()); 15 str = "AbdfSDD"; 16 System.out.println("转小写:"+ str.toLowerCase()); 17 18 str = " 大家最近 都非常努力 "; 19 System.out.println("去除字符串首尾的空格:"+ str.trim()); 20 } 21 }
接下来看看一下String的小练习:
需求1:自己实现trim的方法。
代码示例如下:
1 public static String myTrim(String str){ 2 //先转换成字符 数组 3 char[] arr = str.toCharArray(); 4 //定义两个 变量记录开始与结束 的索引值 5 int startIndex = 0 ; 6 int endIndex = arr.length -1; 7 //确定开始 的索引值 8 while(true){ 9 if(arr[startIndex]==' '){ 10 startIndex++; 11 }else{ 12 break; 13 } 14 } 15 //确定结束 的索引值: 16 while(true){ 17 if(arr[endIndex]==' '){ 18 endIndex--; 19 }else{ 20 break; 21 } 22 } 23 //截取子串返回 24 return str.substring(startIndex,endIndex+1); 25 }
需求2: 获取上传文件名 "D:\JavaCode\Demo1.java"。
代码示例如下:
1 public static void getFileName(String path){ 2 int index = path.lastIndexOf("\"); 3 String fileName = path.substring(index+1); 4 System.out.println("文件名:"+ fileName); 5 }
需求3: 将字符串对象中存储的字符反序。
代码示例如下:
1 public static String reverse(String str){ 2 char[] arr = str.toCharArray(); 3 for(int startIndex = 0 , endIndex=arr.length-1 ; startIndex<endIndex; startIndex++,endIndex--){ 4 char temp = arr[startIndex]; 5 arr[startIndex] = arr[endIndex]; 6 arr[endIndex] = temp; 7 } 8 //使用字符数组构建一个字符串。 9 return new String(arr); 10 }
需求4:统计子串出现 的次数
1 public static void getCount(String str,String target){ 2 int count = 0 ; //用于记录出现的次数 3 int fromIndex = 0; // 记录从那个索引值开始寻找目标子串 4 while((fromIndex = str.indexOf(target, fromIndex))!=-1){ 5 //如果indexof方法返回 的不是-1,那么就是已经找到了目标 元素。 6 count++; 7 fromIndex = fromIndex+target.length(); 8 } 9 System.out.println("出现的次数:"+ count); 10 }