String类
public final class String
String类的特点
String表示字符串,他的值为不可更改的常量,在创建字符串后便不能更改。
内存中有专门的字符串缓冲区,同一个字符串可以被多个对象共享。
当我们创建字符串的时候Java会现在字符串缓冲区寻找有没有相同的,有的话会直接指向他,没有的话会创建一个新的字符串。
String是一种特殊的引用类型,默认值是:null。Java中所有的字符串都相当于是String的实例。
String类本身就重写了toString()方法,所以直接打印一个空的字符串对象是不会输出地址值而是什么都不输出。
字符串的拼接
字符串进行+运算的时候+号此时变为字符串拼接符。
public class Text {
public static void main(String[] args) {
String a = "hello";
a += "word";
System.out.println(a);
String b = "Java";
a += b;
System.out.println(a);
}
}
String类的构造方法
String()
String的无参构造,初始化一个空的字符串对象。
String(byte[ ] bytes)
将一个字节数组通过ASCII码解码转化成字符串:
public class Text {
public static void main(String[] args) {
byte[] arr={97,98,99,100,101,102};
String s=new String(arr);
System.out.println(s); //abcdef
}
}
String(byte[] bytes, int offset, int length)
将一个字节数组的一部分通过ASCII码解码转化成字符串:
offset - 要解码的第一个字节的索引
length - 要解码的字节数
public class Text {
public static void main(String[] args) {
byte[] arr = { 97, 98, 99, 100, 101, 102 };
String s = new String(arr, 1, 4);
System.out.println(s);// bcde
}
}
异常:IndexOutOfBoundsException,offset和 length指定的解码范围超出字节数组的范围。
String(char[] value)
将字符数组转化成字符串。
public class Text {
public static void main(String[] args) {
char[] arr = { '学', '习', 'J', 'A', 'V', 'A' };
String s = new String(arr);
System.out.println(s);// 学习JAVA
}
}
String(char[] value, int offset, int count)
将字符数组的一部分转化成字符串。
offset - 初始偏移量
count - 长度
public class Text {
public static void main(String[] args) {
char[] arr = { '学', '习', 'J', 'A', 'V', 'A' };
String s = new String(arr, 2, 4);
System.out.println(s);// JAVA
}
}
异常:IndexOutOfBoundsException,offset和 count参数的指定的范围超出了字符数组的范围。
String(String original)
将参数中提供的字符串常量创建为一个新的字符串对象。
public static void main(String[] args) {
String s = new String("abcdefg");
String b="qwert";
System.out.println(s);// abcdefg
System.out.println(b);// qwert
}
如上两句,在实际使用中的效果是一样的区别在于:
执行String s = new String("abcdefg");的时候现在堆内存中创建一个字符串对象,然后检查字符串常量池中有没有abcdefg有的话直接返回地址值,没有的话才会创建"abcdefg"。所以相当于创建了两个对象,堆内存中一个常量池中一个。
而执行String b="qwert";的时候不在堆内存创建对象直接去检查字符串常量池中有没有qwert有的话直接返回地址值,没有的话创建"qwert"。所以仅在常量池中创建了一个对象。
String类中常用的方法
转化功能
toCharArray()
将字符串转化为字符数组。
public class Text {
public static void main(String[] args) {
String b = "asdfgh";
char []arr=b.toCharArray();
for(int x=0;x<arr.length;x++) {
System.out.println(arr[x]);
}
}
}
/**输出为:
a
s
d
f
g
h
*/
getBytes()
将字符串转化为字节数组,通过ASCII码进行转化。
public class Text {
public static void main(String[] args) {
String b = "hello123";
byte []arr=b.getBytes();
for(int x=0;x<arr.length;x++){
System.out.print(arr[x]+", ");
}
}
}
/**
* 输出为:104, 101, 108, 108, 111, 49, 50, 51,
*/
valueOf(int i)
将int类型转化成字符串。
public class Text {
public static void main(String[] args) {
int a=12345;
String b=String.valueOf(a);
System.out.println(b); //12345
}
}
这里的valueOf方法是String类的静态方法,通过类名调用使用:
public static String valueOf(int i) {
return Integer.toString(i);
}
valueOf方法有多个重载,支持任意类型基本数据类型转化为字符串。
toLowerCase()
将字符串转化为小写:
public class Text {
public static void main(String[] args) {
String a="HELLOWORD";
System.out.println(a.toLowerCase());//helloword
}
}
toUpperCase()
将字符串转化为大写。
public class Text {
public static void main(String[] args) {
String a="helloword";
System.out.println(a.toUpperCase());//HELLOWORD
}
}
注意:大小写转化仅限于英文。
split(String regex)
分割字符串,通过参数中指定的字符串,将一段字符串进行分割,返回一个字符数组。参数支持正则表达式。
public class Test {
public static void main(String[] args) {
String s = "java=hello=google";
String[] split = s.split("=");
for (String ss : split) {
System.out.println(ss);
}
/*
* java
* hello
* google
*
*/
}
}
比较功能
equals(Object anObject)
字符串中底层本身重写了equals(Object anObject)方法,所以对字符串使用equals方法比较的是字符串的内容。返回值是boolean类型。
public class Text {
public static void main(String[] args) {
String a = "java";
String b = new String("java");
String c = "hello";
String d = "java";
System.out.println(a == b);// false,因为地址不同
System.out.println(a == d);// true,当常量池中已经有"java"再创建的时候会直接将地址指向过去,所以a和d的地址相同
System.out.println(a.equals(b));// true,比较的是内容
System.out.println(a.equals(c));// false
}
}
equalsIgnoreCase(String anotherString)
比较两个字符串是否相等,忽略大小写。返回值为boolean类型
public class Text {
public static void main(String[] args) {
String a = "HELLOword";
String b = "helloword";
System.out.println(a.equalsIgnoreCase(b));// true
}
}
compareTo(String anotherString)
按字典顺序比较两个字符串。比较的是字符串中第一个字符的字典顺序,如果在前返回一个负值,在后返回一个正值,相同返回0。
返回值的大小:
- 两个字符串首字母不同,则该方法返回首字母的ASCII码的差值。
- 两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的ASCII码的差值。
- 两个字符串中短的字符串是长的字符串的开头,则返回两个字符串的长度差值
public class Text {
public static void main(String[] args) {
String a = "abc";
String c = "cbc";
System.out.println(a.compareTo(c));// -2 首字母不同,返回首字母的ASCII码的差值。
System.out.println(c.compareTo(a));// 2
String b = "aec";
System.out.println(a.compareTo(b));// -3 首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的ASCII码的差值。
System.out.println(b.compareTo(a));// 3
String d = "abcdefg";
System.out.println(a.compareTo(d));// -4 短的字符串是长的字符串的开头,则返回两个字符串的长度差值
System.out.println(d.compareTo(a));// 4
}
}
目前compareTo在实际开发中的的作用主要是比较软件的版本号,因为版本号都是固定格式书写,所以会输出相差的版本数。
public class Text {
public static void main(String[] args) {
String a = "1.1.0";
String b = "1.1.5";
System.out.println(a.compareTo(b));// -5
}
}
判断功能
contains(CharSequence s)
判断一个字符串中是否包含另一个字符串,返回值为boolean型,区分大小写。
public class Text {
public static void main(String[] args) {
String b = "helloword大家好";
System.out.println(b.contains("java"));//false
System.out.println(b.contains("owo"));//true
}
}
startsWith(String prefix)
判断当前字符串是否已给定字符串作为开头,返回值为boolean类型。
public class Text {
public static void main(String[] args) {
String b = "helloword大家好";
System.out.println(b.startsWith("hello"));// true
System.out.println(b.startsWith("java"));// false
}
}
endsWith(String suffix)
判断当前字符串是否已给定字符串作为结尾,返回值为boolean类型。
public class Text {
public static void main(String[] args) {
String b = "helloword大家好";
System.out.println(b.startsWith("hel"));// true
System.out.println(b.endsWith("大家好"));// true
}
}
isEmpty()
判断字符串是否为空,返回值为boolean类型
public class Text {
public static void main(String[] args) {
String b = "helloword大家好";
String a = new String();
System.out.println(b.isEmpty());// false
System.out.println(a.isEmpty());// true
}
}
查找功能
length()
返回此字符串的长度。
public class Text {
public static void main(String[] args) {
String b = "qwert";
System.out.println(b.length());// 5
}
}
需要注意在数组中没有length()方法,只有length属性。
集合中没有length(),获取集合的元素数是:size()。
charAt(int index)
返回字符串中指定索引处的字符。计数从0开始。
public class Text {
public static void main(String[] args) {
String b = "helloword大家好";
System.out.println(b.charAt(1));// e
System.out.println(b.charAt(9));// 大
}
}
异常:IndexOutOfBoundsException指定的索引超出字符串的长度范围。
indexOf(int ch)
查找指定字符第一次出现在当前字符串中的位置,计数从0开始。
注意这里参数是int类型,填写int类型查找的是对应ASCII码中的字符。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejava";
System.out.println(b.indexOf(97));//15
System.out.println(b.indexOf('a'));//15
}
}
indexOf(int ch, int fromIndex)
从指定位置开始查找指定字符第一次出现的位置。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejavahellowordilovejava";
System.out.println(b.indexOf('i'));// 9
System.out.println(b.indexOf('i', 10));// 27
}
}
indexOf(String str)
查找指定字符串在当前字符串中第一次出现的索引,返回值为int类型,计数从0开始。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejava";
System.out.println(b.indexOf("word"));// 5
}
}
indexOf(String str, int fromIndex)
从指定位置开始查找指定字符串第一次出现的位置,返回值为int类型,计数从0开始。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejavahellowordilovejava";
System.out.println(b.indexOf("love"));// 9
System.out.println(b.indexOf("love", 11));// 27
}
}
substring(int beginIndex)
返回从指定位置开始到结束的字符串。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejavahellowordilovejava";
System.out.println(b.substring(5)); //wordilovejavahellowordilovejava
System.out.println(b.substring(20)); //llowordilovejava
}
}
substring(int beginIndex, int endIndex)
截取从指定位置开始截取指定长度的字符串。
public class Text {
public static void main(String[] args) {
String b = "hellowordilovejava";
System.out.println(b.substring(5, 9));//word
}
}
注意:这里有个包左不包右的原则,返回的值包含5号位置的w,不包含9号位置的i。
替换功能
replace(char oldChar, char newChar)
用指定字符替换字符串中的某个字符。
public class Text {
public static void main(String[] args) {
String a="helloword";
System.out.println(a.replace('l', 'o'));//heoooword
}
}
replace(CharSequence target, CharSequence replacement)
用指定字符串替换字符串中的某段字符串。
public class Text {
public static void main(String[] args) {
String a="helloword";
System.out.println(a.replace("owo","xxx"));//hellxxxrd
}
}
replaceAll(String regex,String replacement)
使用指定字符串替换给定字符串中满足正则表达式的部分
public class Test04 {
public static void main(String[] args) {
String s = "hello12345World781323244454JavaEE";
String n = s.replaceAll("\\d+", "*");// 替换所有的数字为*
System.out.println(n);// hello*World*JavaEE
}
}
trim()
删除字符串两端的空格
public class Text {
public static void main(String[] args) {
String a=" helloword ";
System.out.println(a);// helloword
System.out.println(a.trim());//helloword
}
}
concat(String str)
和+拼接符效果一样。
public class Text {
public static void main(String[] args) {
String b = "hello";
String a = "word";
System.out.println(b.concat(a));//helloword
}
}
String类例题:
模拟一个登陆系统,可以从已注册的用户信息中识别是哪位用户的账户,并输出这个账户的邮箱类型;登陆有4次机会,登陆失败时候有对应的情况说明。
import java.util.Scanner;
class User {
// 已经注册的用户数据
private static String[] acc = { "[email protected]", "[email protected]", "[email protected]" };
private static String[] pass = { "123456", "456789", "123789" };
// 构造方法私有化,禁止创建该类的对象
private User() {
super();
}
// 账户验证系统
private static String verify(String ac, String pa) {
if (ac.isEmpty() || pa.isEmpty()) {// 判断用户名或密码是否为空
return "账户或密码不能为空";
} else if (ac.endsWith(".com") && ac.contains("@")) {// 检查输入的账户是否包含@且以".com"结尾
for (int i = 0; i < acc.length; i++) {
if (acc[i].equals(ac)) {// 判断账户是否为已注册的账户
if (pass[i].equals(pa)) {// 判断密码是否输入正确
return "恭喜你登陆成功";
} else {
return "密码错误";
}
}
}
return "该账户不存在";
} else {
return "用户名格式不正确,必须为一个邮箱。检查是否为[email protected]格式";
}
}
// 登陆系统
public static void login() {
for (int i = 1; i <= 5; i++) {
System.out.println("请输入用户名(邮箱格式)");
Scanner sc = new Scanner(System.in);
String acc = sc.nextLine().trim().toLowerCase();// trim方法删除输入时两端的空格防止影响判断
// toLowerCase方法将输入内容全部转化为小写,目的是输入的账户不区分大小写,一般邮箱账户没有大小写区分规则。
System.out.println("请输入密码");
Scanner sc2 = new Scanner(System.in);
String pas = sc2.nextLine().trim();//密码中区分大小写所以不需要toLowerCase
if (i <= 4) {
String res = User.verify(acc, pas);// 调用账户验证系统
System.out.print(res);// 输出验证结果
if (res.startsWith("恭喜你")) {// 查找验证结果是否以"恭喜你"开头
System.out.print(",您使用的邮箱是:");
int temp = acc.indexOf('@');// 查找@所在位置的下标
String tempstr = acc.substring(temp);// 截取@以后包含@的字符串
switch (tempstr) {
case "@qq.com":
System.out.println("QQ邮箱");
break;
case "@163.com":
System.out.println("网易163邮箱");
break;
case "@gmail.com":
System.out.println("Google邮箱");
break;
}
break;
} else {
if (4 - i == 0) {// 判断尝试登陆次数是否用尽还没有登陆成功
System.out.println(",登陆机会用尽,请联系后台管理解锁");
break;
} else {
System.out.println(",您还有" + (4 - i) + "次登陆机会");
}
}
}
}
}
}
public class Text {
public static void main(String[] args) {
User.login();
}
}
/**
请输入用户名(邮箱格式)
[email protected]
请输入密码
账户或密码不能为空,您还有3次登陆机会
请输入用户名(邮箱格式)
123456qq.com
请输入密码
123456
用户名格式不正确,必须为一个邮箱。检查是否为[email protected]格式,您还有2次登陆机会
请输入用户名(邮箱格式)
[email protected]
请输入密码
123458
密码错误,您还有1次登陆机会
请输入用户名(邮箱格式)
[email protected]
请输入密码
123456
恭喜你登陆成功,您使用的邮箱是:QQ邮箱
*/
StringBuffer类
特点
- 线程安全,可变的字符序列。字符串缓冲区和String一样但是可以修改。
- StringBuffer可以安全地被多个线程使用。会在必要的时候进行同步。
- 底层实现方式为字节数组。
构造方法
StringBuffer()
构造一个空的的字符串缓冲区,初始容量为16个字符。
StringBuffer(int capacity)
指定容量,构造一个空的的字符串缓冲区。如果知道最终需要的长度建议优先使用。
StringBuffer(String str)
构造一个以指定字符串为内容的字符串缓冲区。
常用的方法
查询
length()
返回字符序列的长度,返回值为int型。
capacity()
返回当前字符序列的容量。
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer();
System.out.println(">>" + s);// >>
// 此时是个空字符串
System.out.println(s.length());// 0
System.out.println(s.capacity());// 16
// 默认容量16个字符
s = new StringBuffer("java");
System.out.println(">>" + s);// >>java
System.out.println(s.length());// 4
System.out.println(s.capacity());// 20
// 系统动态分配容量
}
}
需要注意以下写法不正确:
//StringBuffer s = new StringBuffer();
//s="java";
不能直接将一个字符串赋值给字符序列,需要通过构造方法赋值。
添加
append()
将指定内容追加到字符序列的后面,append有多种重载方法,支持任意类型转化为字符串然后追加到字符序列最后。
class Text {
int i;
public Text(int i) {
super();
this.i = i;
}
}
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer();
s.append("hello");// 字符串
s.append(123);// int类型
s.append('w');// 字符
s.append(true);// Boolean类型
s.append(3.14);// float类型
char[] arr = { 'A', 'B', 'C' };
s.append(arr);// 字符数组
Text t = new Text(200);
s.append(t.i);// 引用类型
System.out.println(s);// hello123wtrue3.14ABC200
}
}
insert(int offset, String str)
将指定字符串添加到字符序列的指定位置,返回值是字符序列本身。
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellojava");
s.insert(5, "word");
System.out.println(s);// hellowordjava
}
}
删除
deleteCharAt(int index)
删除字符序列中指定位置的字符
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellojava");
s.deleteCharAt(5);
System.out.println(s);// helloava
}
}
delete(int start, int end)
删除字符序列中指定位置的字符串,同样存在包左不包右的原则。
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellojava");
s.delete(2, 5);
System.out.println(s);// hejava
}
}
排序
reverse()
反转当前字符序列,返回值是字符序列本身
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellojava");
s.reverse();
System.out.println(s);// avajolleh
}
}
截取
substring(int start)
从指定位置开始截取到结束,返回值是一个新的字符串。
substring(int start, int end)
从指定位置开始截取到指定位置结束,返回值是一个新的字符串,遵循包左不包右。
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellowordjava");
System.out.println(s.substring(5));// wordjava
System.out.println(s.substring(5, 9));// word
}
}
替换
replace(int start, int end, String str)
从指定位置开始到指定位置结束,替换为指定字符串。返回值是字符序列本身。
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellowordjava");
s.replace(5, 9, "Student");
System.out.println(s);//helloStudentjava
}
}
转化
toString()
将字符序列转化成字符串;
public class buffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hellowordjava");
String sr=s.toString();
System.out.println(sr);//hellowordjava
}
}
转化的作用是有时候我们需要使用到String里面的方法
例题
编写一个可以判断输入内容是否为对称字符串的方法
import java.util.Scanner;
public class buffer {
public static void main(String[] args) {
System.out.println("请输入");
Scanner sc = new Scanner(System.in);
if (reversal(sc.nextLine())) {
System.out.println("输入的内容对称");
} else {
System.out.println("输入的内容不对称");
}
}
private static boolean reversal(String a) {
return new StringBuffer(a).reverse().toString().equals(a);
// 链式编程new StringBuffer(a)将输入的字符串转化为字符串序列
// reverse()反转
// toString()转换成String类型
// equals(a)与输入字符串进行对比
}
}
StringBuilder类
此类提供与StringBuffer相同的方法,但不保证同步,缺乏安全性,不能安全使用多线程。但是速度要快得多。
StringBuffer | StringBuilder | Straight |
可变字符序列,相当于容器 | 可变字符序列,相当于容器 | 不可变的字符序列 |
修改StringBuffer,旧的字符串会被清理掉 | 每次对String改变都相当于创建新的字符串,比较耗费内存。 | |
线程安全的且同步的,执行效率低 | 线程不安全的且不同步的,执行效率高,单线程优先采用。 |
StringBuffer | 数组 |
只能在字符串缓冲区储存字符串的容器 | 存储多个数据的容器,并且多个数据的类型必须一致 |
获取缓冲区的长度:length() | 计算数组长度功能:length属性 |