7.Java字符串对象(String|StringBuffer|StringBuilder|StringJoiner)

目录


1. Java基本介绍

2. JDK下载安装及其环境配置

3. 一个简单的java程序

4. Eclipse基本使用、数据类型、运算符

5. 控制语句(if、switch、for、while、foreach)

6. Java数组

7. Java字符串对象(String|StringBuffer|StringBuilder|StringJoiner)

8. Java面向对象

9. 正则表达式

10. Java包装类

11. 日期与时间

12. 异常(throwable)

13. Java日志处理

14. Java集合框架(Collection)

15. Java多线程

16. Java IO数据流

17. Java枚举(Enum)

18. Java泛型

19. Java Class类和Java反射

20. JDBC操作数据库

21. Java网络通信

22. Java注解

23. Java 1.8新特性

24. Java函数式编程


@TOC


String(引用类型)

(1)String是一个引用类型,它本身也是一个class。但是,Java编译器对String有特殊处理,即可以直接用“…”来表示一个字符串
(2)实际上字符串在String内部是通过一个char[]数组表示的;所以可以使用new String(new char[])来创建字符串
(3)Java字符串的一个重要特点就是字符串对象不可变,引用可变。这种不可变性是通过内部的private final char[]字段,以及没有任何修改char[]的方法实现的

两个字符串比较,必须总是使用equals()方法,要忽略大小写比较,使用equalsIgnoreCase()方法


创建字符串(4种)

1.引用字符串常量

直接将字符串常量赋值给String类型变量

String a = "123456";

2.利用构造方法实例化

使用new关键字创建String对象

String a = new String("It’s a dream");

3.利用字符数组实例化

定义一个字符数组charArrays,使用该字符数组创建一个字符串

char[] charArrays = {'t','i','m','e'};
String a = new String(charArrays);		
// 输出:time

4.提取字符数组中的一部分创建字符串对象

定义一个数组,从该字符数组索引3的位置开始,提取2个元素,组成一个新的字符串

char[] charArrays = {'时','间','就','是','金','钱'};
String a = new String(charArrays, 3, 2);	
// 输出:金钱

String实例方法

1.连接字符串(+、+=)

使用+、+=拼接字符串

String a = "abc";
String b = "123";
String c = a + b + "!"; // 使用+拼接字符串。c=abc123!

String d = "拼接字符串";
d += c; // d = 拼接字符串abc123!

2.将指定的字符串连接到此字符串结尾:concat()

wantOnly.concat(str);

wantOnly:原字符串
str:原字符末尾拼接的字符串


3.判断子字符串是否存在:contains()

判断字符串中是否包含指定内容(boolean)

wantOnly.contains(str);

wantOnly:任意字符串
str:查询的子字符串

String str = "肉";
boolean contains1 = str.contains("肉");  //true
boolean contains2 = str.contains("内");  //false

4.获取字符串长度:length()

String num = "123456789";
int size = num.length();

5.获取指定字符:charAt()

wantOnly.charAt(index);

wantOnly:任意字符串对象
index:char值的索引

String str = "床前明月光";
char chr = str.charAt(3); // 月

6.获取子字符串索引位置:indexOf()

用于查找当前字符串中字符或子串,返回字符或子串在当前字符串中从左边起首次出现的位置,若没有出现则返回-1
indexOf(searchStr)


wantOnly.indexOf(searchStr);

wantOnly:任意字符串对象
searchStr:要搜索的字符串

String str = "where are you going";
int size = str.indexOf("e");  // 2

如果是字符串返回第一个字符位置


indexOf(searchStr, formIndex):获取子字符串索引位置,指定开始位置

wantOnly.indexOf(searchStr, fromIndex);

wantOnly:任意字符串对象
searchStr:要搜索的子字符串
fromIndex:开始搜索的索引位置(int)

String str = "It’s a dream";
int size = str.indexOf("s",1);  // 3

lastIndexOf(searchStr):返回指定子字符串最后出现的索引

wantOnly.lastIndexOf(searchStr);

wantOnly:任意字符串对象
searchStr:要搜索的字符串


lastIndexOf(searchStr, formIndex):指定位置搜索最后出现的索引

wantOnly.lastIndexOf(searchStr, fromIndex);

wantOnly:任意字符串对象
searchStr:要搜索的子字符串
fromIndex:开始搜索的索引位置


7.判断是否以指定字符串开始或结尾(都是boolean类型)

(1)startsWith(开始)

wantOnly.startsWith(prefix);

wantOnly:任意字符串
prefix:作为前缀的字符串

String wantOnly = "这是好东西";
boolean size = wantOnly.startsWith("这");

指定开始位置

wantOnly.startsWith(prefix, index);

wantOnly:任意字符串对象
index:开始查找的位置

(2)endsWith(结尾)

wantOnly.endsWith(suffix);

wantOnly:任意字符串
suffix:指定的后缀字符串


8.获取字符数组:toCharArray()

将字符串转换成一个字符数组

wantOnly.toCharArray();

String str = "这是一个字符串";
char[] ch = str.toCharArray();

9.截取字符串:substring()

wantOnly.substring(int beginIndex);

wantOnly:任意字符串
beginIndex:起始索引(int,包括)

String wantOnly = "这是一颗心";
String subStr = wantOnly.substring(2);  // 一颗心

指定开始位置

wantOnly.substring(int beginIndex, int endIndex);

wantOnly:任意字符串
beginIndex:起始索引(包括)
endIndex:结束索引(不包括)

String wantOnly = "优秀的人还是优秀";
String subStr = wantOnly.substring(0, 4); // 优秀的人

10.字符串替换:replace()

replace()

wantOnly.replace(oldstr, newstr);

wantOnly:任意字符串
oldstr:要被替换的字符串序列
newstr:替换后的字符串序列

String wantOnly = "明月几时有,把酒问青天";
String reStr = wantOnly.replace("月", "日"); // 明日几时有,把酒问青天

replaceAll()
将指定字符串替换成新的字符串

wantOnly.replaceAll(regex,replacement);

wantOnly:任意字符串
regex:被替换的字符串或正则表达式
replacement:替换后的字符串

replaceFirst()
将第一个指定的字符串替换成新的字符串。支持正则表达式

wantOnly.replaceAllFirst(regex,replacement);

wantOnly:任意字符串
regex:第一个被替换的字符串或正则表达式
replacement:替换后的字符串

String wantOnly = "8I want to marry you.";
String replaceFirst = wantOnly.replaceFirst("\\d",":");
System.out.println(replaceFirst);//:I want to marry you.

11.字符串分割:split()

split(regex)
根据给定的分隔符对字符串进行拆分,支持正则表达式,最后返回一个字符串数组

wantOnly.split(regex);

wantOnly:任意字符串
regex:分隔符表达式

String wantOnly = "我,想,打,你";
String[] strArray = wantOnly.split(","); // 让字符串按照“,”分割
String string = Arrays.toString(strArray);
System.out.println(string); //[我, 想, 打, 你]

split(regex,limit)
根据分隔符对字符进行拆分,并限定拆分次数。支持正则表达式

wantOnly.split(regex, limit);

wantOnly:任意字符串
regex:分隔符表达式
limit:限制的分割次数(int)

String wantOnly = "a,b,c";
String[] arrStr = wantOnly.split(",", 2); // [a] [b,c]
for(String arr : arrStr) {
	System.out.println(arr);
}

12.大小写转换:toLowerCase()、toUpperCase()

wantOnly.toLowerCase();  // 转换为小写
wantOnly.toUpperCase();  // 转换为大写
wantOnly.toLowerCase(Locale);
wantOnly.toUpperCase(Locale);

Locale
java.util.Locale主要在软件的本地化时使用。它本身没有什么功能,更多的是作为一个参数辅助其他方法完成输出的本地化

Locale myLocale = Locale.getDefault();
System.out.println(myLocale.getCountry());   // CN
System.out.println(myLocale.getLanguage());  // zh
System.out.println(myLocale.getDisplayCountry());  // 中国
System.out.println(myLocale.getDisplayLanguage()); // 中文

13.去除空白内容:trim()、replaceAll()

trim():去除首尾空白内容

wantOnly.trim();

replaceAll():去除所有空白内容
利用正则表达式\s,将所有空白内容换成空字符

String str = "  1       2     3";
String newstr = str.replaceAll("\\s", "");  // 123

14.比较字符串是否相等:equals()、equalslgnoreCase()

boolean equals(Object anotherObject)
比较当前字符串和参数字符串,在两个字符串相等的时候返回true,否则返回false

wantOnly.equals(str);

wantOnly:任意字符串
str:进行比较的字符串

str1.equals(str2);

注意
(1)若两边的变量是基本类型,则只要它们数值相等,就判断这两个变量相等,返回true。
(2)若
两边的变量是引用变量,则 ==比较的是这两个变量的内存地址,只有它们指向同一个对象时,才会返回true

equals比较的是两个对象的内容,如果不重写equals方法,自动调用Object的equals方法(重写后比较的是内存地址),则和“==”一样。但String和Integer,默认重载了Object类的equals方法(重载后比较的是对象的内容)

boolean equalslgnoreCase(anotherString)
字符串对象比较,忽略大小写(长度相等,并且字符相等(忽略大小写),则认为相等)

wantOnly.equalslgnoreCase(anotherString);

wantOnly:任意字符串
anotherString:进行比较字符串


15.判断字符串是否为空:==、equals()

需要判断str是否等于null和””

wantOnly == null
wantOnly.equals("");

16.格式化字符串:format()

使用指定格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用本地默认的语言方法

wantOnly.format("", 0);

format:任意字符串
args:格式字符串中由格式说明引用的参数,如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数是可变的,可以为0

format(Locale locale, String format, Object… args);

参数 描述
locale 格式化过程中要应用的语言环境
format 格式字符串
args 格式字符串中由格式说明符引用的参数,如果还有格式说明符以外的参数,则忽略这些额外的数目是可变的,可以为0

17.字符串比较:compareTo()

int compareTo(String anotherString)
对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0
比较规则:拿出字符串的第一个字符与参数的第一个字符进行比较,如果两者不等,比较结束,返回两者的ascii差。这里有一点需要注意:如果两个字符串的长度不同,并且一个字符串与另一个字符串的前面N个字符相等,那么这个方法返回返回两个字符串长度之差

int compareToIgnore(String anotherString)
与compareTo方法相似,但忽略大小写


String类方法

返回值都是static String

方法 描述
valueOf(int i) 返回int参数的字符串int形式
valueOf(long l) 返回long参数的字符串long形式
valueOf(char c) 返回char参数的字符串char形式
valueOf(char[] data) 返回char数组参数的字符串char形式
valueOf(char[] data, int offset, int count) 返回char数组参数的特定子阵列的字符串char形式
valueOf(float f) 返回float参数的字符串float形式
valueOf(double d) 返回double参数的字符串double形式
valueOf(boolean b) 返回boolean参数的字符串boolean形式
valueOf(Object obj) 返回Object参数的字符串Object形式

StringBuilder(JDK 1.5)

(1)StringBuilder是可变对象,用来高效拼接字符串
(2)StringBuilder支持链式操作,实现链式操作的关键是返回实例本身
(3)StringBuffer是StringBuilder的线程安全版本,现在不需要使用

Java编译器对String做了特殊处理,可以直接用“+”拼接字符串。String虽然可以直接拼接字符串。但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率

注意:对于普通的字符串“+”操作,并不需要将其改写为StringBuilder,因为Java编译器在编译时就自动把多个连续的“+”操作编码为StringConcatFactory的操作。在运行期,StringConcatFactory会自动把字符串连接操作优化为数组复制或者StringBuilder操作

为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区。这样,往StringBuilder中新增字符时,不会创建新的临时对象。查看StringBuilder的源码,可以发现,进行链式操作的关键:定义的append()会返回this,这样,就可以不断调用自身的其他方法

注意:对于普通的字符串“+”操作,并不需要将其改写为StringBuilder,因为Java编译器在编译时就自动把多个连续的 + 操作编码为StringConcatFactory的操作。在运行期,StringConcatFactory会自动把字符串连接操作优化为数组复制或者StringBuilder操作

StringBuffer是Java早期的一个StringBuilder的线程安全版本,它通过同步来保证多个线程操作StringBuffer也是安全的,但是同步会带来执行速度的下降。StringBuilder和StringBuffer接口完全相同


进行链式操作

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder(1024);
        sb.append("Mr ")
          .append("Bob")
          .append("!")
          .insert(0, "Hello, ");
        System.out.println(sb.toString());
    }
}

查看StringBuilder的源码,可以发现,进行链式操作的关键是,定义的append()方法会返回this,这样,就可以不断调用自身的其他方法


不断增加的计数器

仿照StringBuilder,也可以设计支持链式操作的类

1.Adder.java

class Adder {
	private int sum = 0;
	public Adder add(int n) { // 求和
		sum += n;
		return this;
	}
	public Adder inc() { // 加1
		sum++;
		return this;
	}
	public int value() { // 值
		return sum;
	}
}

2.Test.java

public class Test {
	// 链式操作
	public static void main(String[] args) {
		Adder adder = new Adder();
		adder.add(3).add(5).inc().add(10);
		System.out.println(adder.value());
	}
}	

StringBuffer(JDK 1.0)

StringBuffer是线程安全的可变符序列,一个类似于String的字符串缓冲区String创建的字符串对象是不可修改的,StringBuffer类创造的字符串序列是可修改的,且实体容量会随着存放的字符串增加而自动增加

StringBuffer,这是Java早期的一个StringBuilder的线程安全版本,它通过同步来保证多个线程操作StringBuffer也是安全的,但是同步会带来执行速度的下降
StringBuilder、StringBuffer接口完全相同

创建StringBuffer类

创建一个StringBuffer对象必须用new方法

StringBuffer ss = new StringBuffer();       // 无初始值
StringBuffer ss = new StringBuffer("asd"); // 初始值为asd
StringBuffer ss = new StringBuffer(16);    // 初始容量为32个字符

方法

1.添加字符append()

将参数换成字符串,将所有所得字符串中的字符追加到此序列中(跟String类型的concat类似)

sbf.append(obj)

sbf:任意StringBuffer对象
obj:任意数据类型的对象,例如Sting、double、int、Boolean等,都转变此成字符串的表示形式

2.将给定索引处的字符修改为setCharAt()

sbf.chsetCharAt(int index,char ch);

sbf:任意StringBuffer对象
index:被替换的字符
ch:替换字符

3.将一个字符串插入此字符串序列中insert()

sbf.insert(int offset,String str)

sbf:任意StringBuffer对象
offset:插入的索引
str:插入的字符串

4.将字符串反序输出(也就是索引反序)reverse()

sbf.reverse();

5.移除序列子字符串中的字符delete()

移除该序列的子字符串中的字符,该子字符串是从指定的索引start处开始,一直到索引end处结束

sbf.delete(int start,int end);

sbf:任意StringBuffer对象
start:起始索引(包含)
end:结束索引(不包含)


其他方法

方法 描述
sbf.length() 获取字符串长度
sbf.charAt(5) 获取索引为5的字符
sbf.indexOf(str) 获取str所在字符索引位置
sbf.substring(0,2) 截取索引0-2之间的字符串
sbf.replace(2,5,”123”) 将索引2-5之间替换成123

三者相互转换

// String转换为StringBuffer、StringBuilder
String str = "str123";
// String-->StringBuffer
StringBuffer sb = new StringBuffer(str); 
// String-->StringBuilder
StringBuilder sd = new StringBuilder(str);

// StringBuffer、StringBuilder转换为String
// StringBuffer-->String
String a = sb.toString(); 
// StringBuilder-->String
String b = sd.toString();

// StringBuffer相互转换StringBuilder
// StringBuilder-->StringBuilder
StringBuffer sb1 = new StringBuffer(sd.toString());   
// StringBuffer-->StringBuilder
StringBuilder sd1 = new StringBuilder(sb.toString()); 

三者比较

类名 String StringBuilder StringBuffer
对象类型 字符串常量 字符串常量 字符串常量
线程安全性 不安全 不安全 安全
执行效率

String只能赋值一次,每一次内容发生改变都生成了一个新的对象,如何原有的对象引用新的对象
StringBuffer、StringBuilder则不同,每次操作都是对自身对象做操作,而不是生成新的对象

StringBuffer和StringBuilder
StringBuffer和StringBuilder也存在不同之处,StringBuffer的方法使用了“synchronized”关键字进行修饰,这样保证了同时最多只有一个线程可以运行这些方法,保证了线程的安全

StingBuilder则不具备这样的特点。反过来说,正因为StringBuilder没有线程安全机制,运行起来就不用考虑线程加锁,所以运行效率会比StringBuffer要高


适用场合

(1)操作少、数据少、用String
(2)单线程、操作多、数据多、用StringBuilder
(3)多线程、操作多、数据多、用StringBuffer
要高效拼接字符串,应该使用StringBuilder


StringJoiner

原有的StringBuilder太死板,不支持分割;类似分隔符拼接数组的需求很常见,所以Java标准库还提供了一个StringJoiner

StringJoiner是java.util包中的一个类,**用于构造由定界符分隔的字符序列(可选),并提供的前缀开始、后缀结尾。**虽然这也可以在StringBuilder类的帮助下在每个字符串之后附加分隔符,但StringJoiner提供了简单的方法来实现,而无需编写大量代码

StringJoiner类共有2个构造函数,5个公有方法。其中最常用的方法就是add()和toString(),类似于StringBuilder中的append方法和toString方法

实现原理:依赖StringBuilder实现,性能和StringBuilder差不多,同样也是非线程安全的

在向StringJoiner添加内容之前,有时情况下,其sj.toString()将返回prefix + suffix。但是,如果调用setEmptyValue()方法,则将返回提供的emptyValue。这可以使用,例如,创建使用组表示法来表示空集,即一个字符串时“{}”,其中prefix是“{”,所述suffix是“}”,没有什么已被添加到StringJoiner

查看源码,可以发现,StringJoiner内部实际上就是使用了StringBuilder,所以拼接效率和StringBuilder几乎是一模一样的

StringJoiner指定“开头”和“结尾”

String[] names = {"Bob", "Alice", "Grace"};
var sj = new StringJoiner(", ", "Hello ", "!"); // var是JDK 10新特性
for (String name : names) {
sj.add(name);
}
System.out.println(sj.toString());

输出:Hello Bob, Alice, Grace!


拼接List

List list = new ArrayList();
list.add("Red");
list.add("Green");
list.add("Blue");
StringJoiner stringJoin = new StringJoiner(",", "PREFIX-", "-SUFFIX");
for (String str : list) {
	stringJoin.add(str);
}
System.out.println(stringJoin.toString());

输出:PREFIX-Red,Green,Blue-SUFFIX

构造方法

(1)StringJoiner(CharSequence delimiter)
(2)StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
构造一个StringJoiner,使用分隔符、拼接前缀、拼接后缀

参数 描述
delimiter 分隔符。并不是可变字符串的初始值
prefix 拼接后的字符串的前缀
suffix 拼接后的字符串的后缀

常用方法

(1)StringJoiner add(CharSequence newElement):增加需要分割拼接的字符串

将给定的副本CharSequence值作为下一个元素StringJoiner值

(2)int length():获取分割拼接后长度

返回此StringJoiner的String表示形式的StringJoiner

(3)StringJoiner merge(StringJoiner other):增加需要分割拼接的StringJoiner

添加给定StringJoiner的内容,不带前缀和后缀作为下一个元素(合并另外一个StringJoiner内容,不带前后缀。跟add()效果一个,不过是一个拼接完成的StringJoiner在进行拼接)

(4)StringJoiner setEmptyValue(CharSequence emptyValue):空时输出

设置在确定此StringJoiner的字符串表示形式时要使用的字符序列,并且尚未添加任何元素,即它为空时
CharSequence是一个接口,提供参数必须实现此接口(String、StringBuilder、StringBuffer)

(5)String toString():转为字符串

返回当前值,包括prefix前缀、最终由delimiter分隔的值、suffix后缀
如果在这种情况下未使用add()添加任何元素,否则返回prefix + suffix或字符emptyValue


String.join()

String还提供了一个静态方法join(),这个方法在内部使用了StringJoiner来拼接字符串,在不需要指定“开头”和“结尾”的时候,用String.join()更方便
static String join(CharSequence delimiter, CharSequence… elements)

String[] names = {"Bob", "Alice", "Grace"};
var sj = String.join(", ", names);
// 输出sj值:Bob, Alice, Grace

如果日常开发中,需要进行字符串拼接,如何选择?
(1)如果只是简单的字符串拼接,考虑直接使用"+"即可
(2)如果是在for循环中进行字符串拼接,考虑使用StringBuilder和StringBuffer
(3)如果是通过一个集合(如List)进行字符串拼接,则考虑使用StringJoiner
(4)如果是对一组数据进行拼接,则可以考虑将其转换成Stream,并使用StringJoiner处理

你可能感兴趣的:(Java,java,jvm,开发语言)