Java基础——彻底掌握String类

云惠网小编 2022年1月16日07:18:32
评论
7052字阅读23分30秒
摘要

前言:Java中有三大特殊类需要我们系统掌握,分别是String类,Object类以及包装类,这里,我们主讲String类,彻底掌握String类的使用1.常见创建字符串的三种方式// 直接赋值法 String str1 = “hello”;// 使用关键字new String str2 = new String(“hello”);// 使用char[] char[] data = {‘h’,’e’,’l

广告也精彩

8.4 字符串拆分

5.1 为什么有不可变性

8.2 字符串查找

 这就是因为字符串的不可变性,change 方法是新创建了一个字符串,并不是修改了原来的字符串,真实的内存如下图:

互相转化代码实现如下:

(1)通常修改字符串的内容,我们选择使用 += 拼接,借助原字符串, 创建新的字符串,如下:

7.1 String类型和char[ ] 类型

append()方法,拼接扩展

内部存储如下:

  • 如使用直接赋值法,String str = "Hello"

3. 字符串的常量池

  • equals()方法
  • equalsIgnoreCase()方法,不区分大小写的比较
  • compareTo()方法,与equals()方法不同的是,该方法返回的是整数:

8.3 字符串替换

8.1 字符串比较:

正常输入,两种形式都OK

    public static void main(String[] args) {
String str = "HiHello";
String str2 = "H";
System.out.println(str.contains("H"));
System.out.println(str.indexOf("ll"));
System.out.println(str.lastIndexOf("ll"));
System.out.println(str.startsWith("Hi"));
System.out.println(str.endsWith("lo"));
}
    public static void main(String[] args) {
StringBuilder s = new StringBuilder("hello");
//        反转字符
s.reverse();
//        输出 olleh
System.out.println(s);
//        删除
s.delete(1,3);
//        输出 oeh
System.out.println(s);
//        插入
s.insert(1,"zzzz");
//        输出 ozzzzeh
System.out.println(s);
}

8. String类的其他常用操作 

 3.2 手工入池

2.1 不同的内存空间

 3.2 手工入池

6. StringBuilder类

2. 字符串的内存布局

6.1 String 类与StringBuilder类的相互转化

 7.3 小结:

目录

输出结果如下:

如下,注意区别:

输出结果:

2.1 不同的内存空间

(2)这里我们就可以用intern()方法实现人工入池

6.2 StringBuilder类的其他方法

这就是String类的全部内容了,其中最核心的还是要能够理解常量池,以及字符串的不变性 

结果:


3. 字符串的常量池

 4. 小结一

(2)不可变的好处:

    public static void main(String[] args) {
String str = "Hi.He.llo";
//        截取字符串
System.out.println(str.substring(1));
System.out.println(str.substring(1,4));
//        字符串长度
System.out.println(str.length());
//        判断是否为空
System.out.println(str.isEmpty());
//        转大写字母
System.out.println(str.toUpperCase());
//        转小写字母
System.out.println(str.toLowerCase());
}

 

    public static void main(String[] args) {
String str = "HiHello";
System.out.println(str.replaceAll("H","zzzz"));
System.out.println(str.replaceFirst("H","yyyy"));
}

前言:Java中有三大特殊类需要我们系统掌握,分别是String类,Object类以及包装类,这里,我们主讲String类,彻底掌握String类的使用

 如:

8.5 字符串的截取

  • str.length()获取长度
  • str.isEmpty() 判断是否为空
  • toUpperCase()  全部转大写
  • toLowerCase() 全部转小写
  • trim() 去掉字符串前后空格,而保留中间空格
public class StringPractice {
public static void main(String[] args) {
String str1 = "Hello";
//        String -> StringBuilder
//        构造方法
StringBuilder s1 = new StringBuilder(str1);
//        append()方法
StringBuilder s2 = new StringBuilder("hello");
s2.append("world");
//        StringBuilder -> String
String s3 = s2.toString();
}
}

8.1 字符串比较:

7. String类型和char[ ] 类型、byte[ ]类型的相互转化

byte[] 是把 String 按照一个字节一个字节的方式处理, 这种适合在网络传输, 数据存储这样的场景下使用. 更适合针对二进制数据来操作.

char[] 是把 String 按照一个字符一个字符的方式处理, 更适合针对文本数据来操作, 尤其是包含中文的时候

    public static void main(String[] args) {
String str1 = new String("Hello");
String str2 = "Hello";
System.out.println(str1 == str2);
}

当使用直接赋值法创建字符串时,JVM会对字符串创建一个字符串的常量池,常量池的主要目的就是为了保证效率和高复用

6.2 StringBuilder类的其他方法

    public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2);
}
  • contains(String s) 方法,判断子字符串是否存在
  • indexOf(String s) 方法,从前向后查,返回s开始位置索引
  • lastIndexOf(String s)方法,从后向前查,返回s开始位置索引
  • startsWith(String s) 方法,判断是否以指定字符串开头
  • endsWith(String s)方法,判断是否以指定字符串结尾

8.4 字符串拆分

5. 字符串的不可变性

 

因为String是引用数据类型,存储的是地址,故而,我们可以得到字符串比较相等时,不可以直接使用 == 进行比较,而要使用equals()方法

结果:

如下面这段代码,

  • 而使用new关键字创建,则会创建不止一个对象,如这一句代码:
    String str2 = new String("Hello")

    这里,hello作为字符串字面常量是一个对象,而因为又使用了new关键字又开辟了一个空间,这个空间会把字符串字面量拷贝复制过来,故而,其实产生了两个对象,字符串字面量是一个垃圾空间

//        直接赋值法
String str1 = "hello";
//        使用关键字new
String str2 = new String("hello");
//        使用char[]
char[] data = {'h','e','l','l','o'};
String str3 = new String(data);

输出结果: 

6.1 String 类与StringBuilder类的相互转化

2. 字符串的内存布局

(2)要想真正修改原字符串,只能通过反射来破环封装,这里了解即可,不再延申

    public static void main(String[] args) {
String str1;
Scanner scanner = new Scanner(System.in);
str1 = scanner.next();
//        比较用户输入的字符串是否为“Hello”
//        形式一
System.out.println(str1.equals("Hello"));
//        形式二
System.out.println("Hello".equals(str1));
}

1. 字符"|","*","+"都得加上转义字符,前面加上"\"

2. 而如果是".",那么就得写成"\\."

3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符

Hi
He
llo
Hi
He llo

    public static void main(String[] args) {
String str = "Hi.He.llo";
//        以空格分割
String[] s = str.split("\\.");
for(String a : s){
System.out.println(a);
}
}

 == 比较的是str1和str2所存储的地址,输出true说明str1,str2指向的是同一个字符串

但如果当str1为默认值Null时,形式一会出现空指针异常

但这里其实并不是真正的修改了原字符串,是通过创建新的字符串实现的,先创建了字面量World,然后 + 号创建了HelloWorld,最后 = 使str1指向了新的字符串HelloWorld,但是JVM没有那么笨拙,碰到 + 号,JVM会将字符串转为StringBuilder类

(3)insert(int start,待插入数据) 将索引下标为start的位置插入数据

(3)通常,如果想大量修改字符串的内容,我们会用到StringBuffer类,和StringBuilder类,这两个类的区别在于,StringBuffer类是线程安全的,StringBuilder类是线程不安全的但效率要高

一般,就用直接赋值法创建字符串即可,然后用equals()方法比较值相等

(1)对于基本数据类型,== 比较的就是两个变量的值,但是对于引用数据类型,== 比较的其实是其存储的地址,所以不能直接用 == 比较

 4. 小结一

2.2 字符串的比较

(1)由于String类内部并未提供getter方法,所以外部无法使用到存储字符串真实的char数组,所以,有关修改的操作都并不是真正的修改了原来的字符串,大都是通过创建一个新的字符串来达到看似修改的目的

其内部存储如下:(在创建str2时,Hello字面量已经存在,所以str2会直接指向而并不会在堆上再创健一个Hello)

输出结果:

1. 常见的创建字符串的三种方式

输出结果:

true
4
4
true
true

String是引用数据类型,故其存储的也是地址,在栈上保存,它所创建的对象则在堆上存储(这里,如果不懂栈空间、堆空间等可在上一篇Java中的类和对象这一篇中学习)

5.3 字符串的修改

构造方法

同时,由String类前面的final修饰符我们也可以知道,String类是不能再被继承修改的,这样可以保证所有使用JDK的程序员使用的是同一个String类 

8. String类的其他常用操作 

(2)String -> byte[ ]         getBytes()方法

 7.3 小结:

8.5 字符串的截取

由第三种创建方式我们可以知道,String内部仍是使用字符数组来存储元素的,下面是部分源码:

(2)String -> char[ ] 

输出结果:

i.He.llo
i.H
9
false
HI.HE.LLO
hi.he.llo

 【注意】一些特殊的字符作为切割符可能无法区分,需要加上转义字符

5.2 验证不可变性

    public static void main(String[] args) {
String str1 = new String("Hello").intern();
String str2 = "Hello";
System.out.println(str1 == str2);
}

当使用直接赋值法(方式一)创建时,如果所创建的字符串字面值是第一次出现,JVM就会创建对象并将它扔入常量池,而如果该字面值不是第一次出现,JVM会直接从常量池中复用该对象

5.1 为什么有不可变性

    public static void main(String[] args) {
String str = "Hi He llo";
//        以空格分割
String[] s = str.split(" ");
for(String a : s){
System.out.println(a);
}
//        以空格分割,数组长度为2
String[] s2 = str.split(" ",2);
for(String a : s2){
System.out.println(a);
}
}

toString()方法

1. 常见的创建字符串的三种方式

7.1 String类型和char[ ] 类型

(2)delete(int start,int end) 删除指定范围内的字符,左闭右开 ,start,end均为字母索引下标,从0开始数

8.3 字符串替换

6. StringBuilder类

5. 字符串的不可变性

7.2 String类型和byte[ ]类型

(1)reverse()方法,反转字符

  • charAt(int index) 方法,返回指定索引处的字符
  • toCharArray() 方法,将字符串转变为字符数组

(1)char[ ] -> String 即文章开篇写到的第三种创建字符串的方式

 所以,一般由直接赋值法创建对象即可

7.2 String类型和byte[ ]类型

5.2 验证不可变性

8.6 其他方法

3.1 自动入池

这里输出的就是false了, 也验证了这种创建方法并不会入常量池

    public static void main(String[] args) {
String str = "Hello";
char a = str.charAt(1);
char b[] = str.toCharArray();
System.out.println(a);
System.out.println(b);
}

(2)StringBuilder -> String

2.2 字符串的比较

 结果:

zzzzizzzzello
yyyyiHello

8.6 其他方法

  • replaceAll(String regex,String replacement) 将所有的regex替换为replacement
  • replaceFirst(String regex,String replacement) 仅将第一次遇到的regex替换为replacement

public class StringPractice {
public static void main(String[] args) {
String str = "Hello";
change(str);
System.out.println(str);
}
public static void change(String s){
s = "Hi";
}
}
  • subString(int beginIndex) 从beginIndex处开始截取到末尾
  • subString(int beginIndex,int endIndex) 从beginIndex处开始截取到endIndex,左闭右开

(1)String -> StringBuilder

    public static void main(String[] args) {
byte[] b = {'h','i'};
//        byte[ ] 全部转为String类型,构造
String str1 = new String(b);
//        从0开始长度为1的数组部分转变为String
String str2 = new String(b,0,1);
System.out.println(str1);
System.out.println(str2);
//        String -> byte[]
byte[] b2 = str1.getBytes();
System.out.println(Arrays.toString(b2));
}

(1)当使用其他方法创建字符串时,并不会自动入池,如下面这段代码:

5.3 字符串的修改

1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑何时深拷贝字符串的问题了.

2. 不可变对象是线程安全的.

3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.

3.1 自动入池

(2)equals的用法需注意,以下两种形式,建议第二种,尤其是当str1为用户输入时,如果用户未输入,那么str1默认为null,形式一的写法就有可能造成空指针异常

如下面这段代码:

  • public String[ ] split(String regex) 将字符串按regex拆分
  • public String[ ] split(String regex,int limit) 将字符串按regex拆分,数组长度为limit

(1)byte[ ] -> String 仍然用String的构造方法,可选择范围也可直接全部转换

7. String类型和char[ ] 类型、byte[ ]类型的相互转化

        String str1 = "Hello";
str1 += "World";
System.out.println(str1);

我们期望的输出结果是将str1的Hello变更为Hi,但我们来看真实的输出结果:

8.2 字符串查找

1. 相等:返回0.

2. 小于:返回内容小于0.

3. 大于:返回内容大于0

(字符串的比较大小规则, 总结成三个字 "字典序" 相当于判定两个字符串在一本词典的前面还是后面. 先比较第一个字符的大小(根据 unicode 的值来判定), 如果不分胜负, 就依次比较后面的内容)

本文转自 https://blog.csdn.net/m0_58652786/article/details/122486814

腾讯云618
云惠网小编
SpringCloud -- Config、Bus解析 java

SpringCloud — Config、Bus解析

1、Config1.1、概述简介1. 分布式面临的问题微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要...
Java数据结构-了解复杂度 java

Java数据结构-了解复杂度

2.实例分析与计算  四.写在最后  // 计算斐波那契递归fibonacci的时间复杂度 int fibonacci(int N) { return N < 2 ? N : fibonacci...
Java数据结构-认识顺序表 java

Java数据结构-认识顺序表

目录二.顺序表1.概念及结构2.顺序表的实现打印顺序表获取顺序表的有效长度在pos位置新增元素判断是否包含某个元素查找某个元素对应的位置获取/查找pos位置的元素给pos位置的元素...
腾讯云618

发表评论