String类
String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!
String类的特点
- String类:代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
- String是一个final类,代表不可变的字符序列。
- 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改
- 虽然 String 的值是不可变的,使用=号创建的字符串对象,都在常量池中,它们可以被共享。
- 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
常用构造方法
代码举例
package com.wrg; /* String构造方法: public String():创建一个空白字符串对象,不含有任何内容 public String(char[] chs):根据字符数组的内容,来创建字符串对象 public String(byte[] bys):根据字节数组的内容,来创建字符串对象 String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc 推荐使用直接赋值的方式得到字符串对象 */ public class StringDemo { public static void main(String[] args) { //public String():创建一个空白字符串对象,不含有任何内容 String s1 = new String(); System.out.println("s1:" + s1);//s1: //public String(char[] chs):根据字符数组的内容,来创建字符串对象 char[] chs = {'a', 'b', 'c'}; String s2 = new String(chs); System.out.println("s2:" + s2);//s2:abc //public String(byte[] bys):根据字节数组的内容,来创建字符串对象 byte[] bys = {97, 98, 99}; String s3 = new String(bys); System.out.println("s3:" + s3);//s3:abc //String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc String s4 = "abc"; System.out.println("s4:" + s4);//s4:abc } }
创建字符串对象两种方式的区别
- 通过构造方法创建:通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同
- 直接赋值方式创建:以“”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护
示例:
package com.wrg; /* 使用 == 做比较: 基本类型:比较的是数据值是否相同 引用类型:比较的是地址值是否相同 */ public class StringDemo { public static void main(String[] args) { //构造方法的方式得到对象 char[] chs = {'a', 'b', 'c'}; String s1 = new String(chs); String s2 = new String(chs); //直接赋值的方式得到对象 String s3 = "abc"; String s4 = "abc"; //比较字符串对象地址是否相同 System.out.println(s1 == s2);//false System.out.println(s3 == s4);//true } }
注意:
- 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
- 只要其中有一个是变量,结果就在堆中
- 如果拼接的结果调用intern()方法,返回值就在常量池中
String常用方法
- int length():返回字符串的长度: return value.length
- char charAt(int index): 返回某索引处的字符return value[index]
- boolean isEmpty():判断是否是空字符串:return value.length == 0
- String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
- String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
- String trim():返回字符串的副本,忽略前导空白和尾部空白
- boolean equals(Object obj):比较字符串的内容是否相同
- boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
- String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
- int compareTo(String anotherString):比较两个字符串的大小
- String substring(int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex开始截取到最后的一个子字符串。
- String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字 符串从beginIndex开始截取endIndex(不包含)的一个子字符串。
- boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
- boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
- boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的 子字符串是否以指定前缀开始
- boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列 时,返回 true
- int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
- int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出 现处的索引,从指定的索引开始
- int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
- int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后 一次出现处的索引,从指定的索引开始反向搜索 注:indexOf和lastIndexOf方法如果未找到都是返回-1
- String replace(char oldChar, char newChar):返回一个新的字符串,它是 通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
- String replaceAll(String regex, String replacement) : 使 用 给 定 的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
- String replaceFirst(String regex, String replacement) : 使 用 给 定 的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
- boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
- String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
- String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此 字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
小知识:
String.join()方法是JDK1.8之后新增的一个静态方法,第一个参数为拼接符号,第二个参数为数组和集合 或者字符串。使用方式如下所示:
String result = String.join("-","java","c++","c#","ruby"); //输出结果如下:java-c++-c#-ruby //也可使用如下方式: String[] arr = {"java","c++","c#","ruby"}; String result = String.join("*",arr); //输出结果如下:java*c++*c#*ruby
下面简单举几个例子来说明String方法的使用
案例需求 :已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录之后,给出相应的提示
package demo01; import java.util.Scanner; /* 需求: 已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录之后,给出相应的提示 思路: 1:已知用户名和密码,定义两个字符串表示即可 2:键盘录入要登录的用户名和密码,用 Scanner 实现 3:拿键盘录入的用户名、密码和已知的用户名、密码进行比较,给出相应的提示。字符串的内容比较,用equals() 方法实现 4:用循环实现多次机会,这里的次数明确,采用for循环实现,并在登录成功的时候,使用break结束循环 */ public class StringDemo { public static void main(String[] args) { //已知用户名和密码,定义两个字符串表示即可 String username = "张三"; String password = "123"; //用循环实现多次机会,这里的次数明确,采用for循环实现,并在登录成功的时候,使用break结束循环 for (int i = 0; i < 3; i++) { //键盘录入要登录的用户名和密码,用 Scanner 实现 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String name = sc.nextLine(); System.out.println("请输入密码:"); String pwd = sc.nextLine(); //拿键盘录入的用户名、密码和已知的用户名、密码进行比较,给出相应的提示。字符串的内容比较,用equals() 方法实现 if (name.equals(username) && pwd.equals(password)) { System.out.println("登录成功"); break; } else { if (2 - i == 0) { System.out.println("你的账户被锁定,请与管理员联系"); } else { System.out.println("登录失败,你还有" + (2 - i) + "次机会"); } } } } }
需求:
- 键盘录入一个字符串,使用程序实现在控制台遍历该字符串
package demo01; import java.util.Scanner; /* 需求: 键盘录入一个字符串,使用程序实现在控制台遍历该字符串 思路: 1:键盘录入一个字符串,用 Scanner 实现 2:遍历字符串,首先要能够获取到字符串中的每一个字符 public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的 3:遍历字符串,其次要能够获取到字符串的长度 public int length():返回此字符串的长度 数组的长度:数组名.length 字符串的长度:字符串对象.length() 4:遍历字符串的通用格式 */ public class StringDemo { public static void main(String[] args) { //键盘录入一个字符串,用 Scanner 实现 Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串:"); String line = sc.nextLine(); //获取到字符串的长度 public int length():返回此字符串的长度 //遍历字符串 for (int i = 0; i < line.length(); i++) { // public char charAt(int index):返回指定索引处的char值,字符串的索引也是从0开始的 System.out.print(line.charAt(i)); } } }
需求:
- 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)
package demo01; import java.util.Scanner; /* 需求: 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符) 思路: 1:键盘录入一个字符串,用 Scanner 实现 2:要统计三种类型的字符个数,需定义三个统计变量,初始值都为0 3:遍历字符串,得到每一个字符 4:判断该字符属于哪种类型,然后对应类型的统计变量+1 假如ch是一个字符,我要判断它属于大写字母,小写字母,还是数字,直接判断该字符是否在对应的范围即可 大写字母:ch>='A' && ch<='Z' 小写字母: ch>='a' && ch<='z' 数字: ch>='0' && ch<='9' 5:输出三种类型的字符个数 */ public class StringDemo { public static void main(String[] args) { //键盘录入一个字符串,用 Scanner 实现 Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串:"); String line = sc.nextLine(); //要统计三种类型的字符个数,需定义三个统计变量,初始值都为0 int bigCount = 0; int smallCount = 0; int numberCount = 0; //遍历字符串,得到每一个字符 for (int i = 0; i < line.length(); i++) { char ch = line.charAt(i); //判断该字符属于哪种类型,然后对应类型的统计变量+1 if (ch >= 'A' && ch <= 'Z') { bigCount++; } else if (ch >= 'a' && ch <= 'z') { smallCount++; } else if (ch >= '0' && ch <= '9') { numberCount++; } } //输出三种类型的字符个数 System.out.println("大写字母:" + bigCount + "个"); System.out.println("小写字母:" + smallCount + "个"); System.out.println("数字:" + numberCount + "个"); } }
需求:
- 定义一个方法,实现字符串反转。键盘录入一个字符串,调用该方法后,在控制台输出结果例如,键盘录入 abc,输出结果 cba
import java.util.Scanner; /* 思路: 1:键盘录入一个字符串,用 Scanner 实现 2:定义一个方法,实现字符串反转。返回值类型 String,参数 String s 3:在方法中把字符串倒着遍历,然后把每一个得到的字符拼接成一个字符串并返回 4:调用方法,用一个变量接收结果 5:输出结果 */ public class StringTest05 { public static void main(String[] args) { //键盘录入一个字符串,用 Scanner 实现 Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串:"); String line = sc.nextLine(); //调用方法,用一个变量接收结果 String s = reverse(line); //输出结果 System.out.println("s:" + s); } //定义一个方法,实现字符串反转 /* 两个明确: 返回值类型:String 参数:String s */ public static String reverse(String s) { //在方法中把字符串倒着遍历,然后把每一个得到的字符拼接成一个字符串并返回 String ss = ""; for(int i=s.length()-1; i>=0; i--) { ss += s.charAt(i); } return ss; } }
String与字符数组转换
字符数组 ----> 字符串
- String 类的构造器:String(char[]) 和 String(char[],int offset,int length) 分别用字符数组中的全部字符和部分字符创建字符串对象。
字符串 ------> 字符数组
- public char[] toCharArray():将字符串中的全部字符存放在一个字符数组 中的方法。
- public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):提供了将指定索引范围内的字符串存放到数组中的方法。
字节数组 -----> 字符串
- String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
- String(byte[],int offset,int length) :用指定的字节数组的一部分, 即从数组起始位置offset开始取length个字节构造一个字符串对象。
字符串 ------> 字节数组
- public byte[] getBytes() :使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
- public byte[] getBytes(String charsetName) :使用指定的字符集将 此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
StringBuffer类
概述:java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明,可以对字符 串内容进行增删,此时不会产生新的对象。很多方法与String相同。作为参数传递时,方法内部可以改变值。
StringBuilder类丶String类丶StringBuffer的区别
常用的构造方法
StringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:
- StringBuffer():初始容量为16的字符串缓冲区
- StringBuffer(int size):构造指定容量的字符串缓冲区
- StringBuffer(String str):将内容初始化为指定字符串内容
常用方法
- StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
- StringBuffer delete(int start,int end):删除指定位置的内容
- StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
- StringBuffer insert(int offset, xxx):在指定位置插入xxx
- StringBuffer reverse() :把当前字符序列逆转
代码演示
public class StringBuilderDemo { public static void main(String[] args) { //创建对象 StringBuilder sb = new StringBuilder(); //public StringBuilder append(任意类型):添加数据,并返回对象本身 //链式编程 sb.append("hello").append("world").append("java").append(100); System.out.println("sb:" + sb); //public StringBuilder reverse():返回相反的字符序列 sb.reverse(); System.out.println("sb:" + sb); } }
StringBuilder和String相互转换
- StringBuilder转换为String :public String toString():通过 toString() 就可以实现把 StringBuilder 转换为 String
- String转换为StringBuilder:public StringBuilder(String s):通过构造方法就可以实现把 String 转换为 StringBuilder