《JAVASE系列》String 类

《JAVASE系列》String 类

前言:

本章学习内容:

  1. 熟悉String类的基本用法
  2. 掌握String类的库方法
  3. 认识字符串常量池
  4. 认识StringBuffer与StringBuilder

参考书籍:《java核心卷1》

你若盛开,清风自来。

1. String类的基本用法

1.1 字符串构造

字符串的构造方式很多,常用的一般为以下三种:

public class Main {
    public static void main(String[] args) {
        //直接赋一个常量值
        String s1 = "hello";
        //直接new一个String 对象再赋值给name2
        String s2 = new String("hello");
        //使用字符数组进行构造
        char[] arr = new char[]{'h','e','l','l','o'};
        String s3 = new String(arr);
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }
}

1.2 String是引用类型

String是引用类型,内部并不存储字符串本身

查看String 的源码:

在这里插入图片描述

在这里插入图片描述

我们不难看出,String类的构造方法将传进来字符串是以字符数组存储在String 类中的value字符数组中,所以String内部并不是存储字符串本身,而是拷贝这个字符串存储在字符数组value中。

String类的构造方法并不只有一个,例如s3就调用了另一个构造方法:

在这里插入图片描述

存储的过程如下:

在这里插入图片描述

1.3 String对象的比较

1.3.1 通过 “==” 比较

由于String类型是引用类型

所以: == 比较是否引用同一个对象

public class Main {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        String s3 = s1;
        System.out.println(s1==s3);
        System.out.println(s1==s2);
    }
}

运行结果:

在这里插入图片描述

s3与s1都指向“hello”这个string 对象,二者存储的地址相同,所以二者相等

s1指向“hello”对象,s2指向“world”对象,二者存储的地址不同,所以不相等

至于以下情况:

public class Main {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1==s2);
    }
}

运行结果:

在这里插入图片描述

为什么是true:

与字符串的常量池有关。后续介绍

1.3.2 通过equals比较

equals方法会帮我们比较两个字符串类型变量的内容是否相同,相同返回true,不同返回flase

源码分析:

在这里插入图片描述

equals会先比较两个字符串引用的地址是否相同,如果地址相同,则内容必然相同,返回true。

如果两个字符串的地址不同,会一个一个字符得去比较,如果有一个字符不相等,则返回false,全部都相同返回true。

public class Main {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1.equals(s2));
    }
}

运行结果:

在这里插入图片描述

1.3.3 通过comparTo比较

compareTo源码分析:

在这里插入图片描述

与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:

  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
1.3.4 忽略大小写的比较

equalsIgnoreCase 与 equal 类似,但是忽略大小写的比较

compareToIgnoreCase 与 compare 类似,但是忽略大小写的比较

2.String类常用方法

2.1 字符串查找

字符串查找是字符串中非常常见的操作,String类提供的常用查找的方法:

2.1.1 char charAt

charAt(int index)

返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常。

代码演示:

public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        for (int i = 0; i < str.length(); i++) {
            System.out.print(str.charAt(i)+" ");
        }
    }
}

运行结果:
在这里插入图片描述

2.1.2 int indexOf

1 int indexOf(int ch)

返回ch第一次出现的位置,没有返回 -1

代码演示:

public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        int a = str.indexOf("e");  //得到第一次出现e的下标位置
        System.out.println(a);
    }
}

运行结果:

在这里插入图片描述

2 int indexOf(int ch,int fromIndex)

从fromIndex位置开始找ch第一次出现的位置,没有返回 -1

代码演示:

public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        int a1 = str.indexOf("o",3);  //得到下标为3之后 出现o的下标位置
        int a2 = str.indexOf("o",5);  //得到下标为5之后 出现o的下标位置
        System.out.println(a1);
        System.out.println(a2);
    }
}

运行结果:
在这里插入图片描述

3 int indexOf(String str)

返回字符串 str 第一次出现的位置,没有返回-1

代码演示:

public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        int a1 = str.indexOf("llo");  
        int a2 = str.indexOf("rld");
        System.out.println(a1);
        System.out.println(a2);
    }
}

运行结果:

在这里插入图片描述

4 int indexOf(String str,int fromIndex)

从fromIndex位置开始找字符串 str 第一次出现的位置,没有返回-1

代码演示:

public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        int a1 = str.indexOf("llo",3);
        int a2 = str.indexOf("rld",3);
        System.out.println(a1);
        System.out.println(a2);
    }
}

运行结果:
在这里插入图片描述

2.1.3 int lastIndexOf

与indexOf一样,但是是从字符串最后开始查找。

int lastIndexOf(int ch)

从后往前找,返回ch第一次出现的位置,没有返回-1

int lastIndexOf(int ch, int fromIndex)

从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返回-1

int lastIndexOf(String str)

从后往前找,返回str第一次出现的位置,没有返回-1

int lastIndexOf(String str, int fromIndex)

从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返
回-1

2.2 字符串转化

2.2.1 数值和字符串转化 String.valueOf
public class Main {
    public static void main(String[] args) {
        String str1 = String.valueOf(1234);
        String str2 = String.valueOf(12.34);
       String str3 = String.valueOf(true);
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
     }
}

运行结果:

在这里插入图片描述

2.2.2 大小写转化 str.toUpperCase与str.toLowerCase
public class Main {
    public static void main(String[] args) {
        String str = "HeLLo";
        String str1 = str.toLowerCase();
        String str2 = str.toUpperCase();
        System.out.println(str1);
        System.out.println(str2);
    }
}

运行结果:

在这里插入图片描述

2.2.3 字符串转数组 str.toCharArray
public class Main {
    public static void main(String[] args) {
        String str = "hello";
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.print(chars[i]+" ");
        }
    }
}

运行结果:

在这里插入图片描述

2.2.4 格式化 String.formate
public class Main {
    public static void main(String[] args) {
        String s = String.format("%d-%d-%d",2022,4,18);
        System.out.println(s);
    }
}

运行结果:

在这里插入图片描述

2.3 字符串替换

使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:

  • String replaceAll(String regex, String replacement) 替换所以内容
  • String replaceFirst(String regex, String replacement) 替换首个内容
public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        System.out.println(str.replaceAll("l","xixi"));
        System.out.println(str.replaceFirst("l","xixi"));
    }
}

运行结果:

在这里插入图片描述

也就是说,replaceAll只要字符串中有regex的内容,每份内容都会被替代为replacement的内容

而replaceFirst是只替换掉字符串regex的第一份内容为replacement

2.4 字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。可用方法如下:

  • String[] split(String regex) 拆分所有内容
  • String[] split(String regex, int limit) 拆分成limit组

代码示例:

public class Main {
    public static void main(String[] args) {
        String str = "hello world yes hi";
        String[] arr1 = str.split(" ");
        String[] arr2 = str.split(" ",2);
        for (String S:arr1) {
            System.out.println(S+" ");
        }
        System.out.println();
        for (String S:arr2) {
            System.out.println(S+" ");
        }
    }
}

运行结果:

在这里插入图片描述

注意事项:

注意事项:

  1. 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
  2. 而如果是 “” ,那么就得写成 “\\” .
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

2.5 字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

  • String substring(int beginIndex) 从指定索引截取到结尾
  • String substring(int beginIndex, int endIndex) 截取部分内容
public class Main {
    public static void main(String[] args) {
        String str = "helloworld";
        System.out.println(str.substring(3));
        System.out.println(str.substring(3,6));
    }
}

运行结果:

在这里插入图片描述

2.6 去掉字符串左右的空格

String trim() 去掉字符串中的左右空格,保留中间空格

public class Main {
    public static void main(String[] args) {
        String str = "  helloworld  ";
        System.out.println(str);
        System.out.println(str.trim());
    }
}

运行结果:

在这里插入图片描述

了解String类的内部常量:

在这里插入图片描述

String类被final修饰,表明该类不能被继承.

为什么String类为不可修改字符串:

在上面的代码中,我们可以看到value值是被private修饰的,也就是外部类是无法修改value的值,并且被final修饰,也就意味着当value值被赋值成功后,在String类中也无法再一次得修改这个值.(保证字符内容不可变)

在任何涉及到字符串的截取修改比较等等的方法,都会创建出新的String对象,例如:

在这里插入图片描述

3.字符串常量池:

3.1什么是池:

池是编程中十分常见的用来提升效率的方式,在未来的学习中会遇到许多类似的池化技术,例如:内存池,线程池,数据库连接池,Class文件常量池,运行时常量池…

此处我们着重了解字符串常量池.

3.2字符串常量池(StringTable)

字符串常量池在JVM中是一个StringTable类,实际上是一个固定大小的HashTable.

在java8版本中,字符串常量池的位置位于堆中.大小可设置,有范围限制,最小是1009.

如何将字符串存入字符串常量池的:

  1. JVM 中 字符串常量池是只有一个的,并且作为全局共享.

  2. 一开始的时候,字符串常量池是为空,随着程序的运行,String类对象的不断创建,字符串常量池的元素会越来越多.

  3. 随着类的加载,字节码文件的常量池也被加载到JVM中,(运行时常量池),并且会将字符串常量保存在字符串常量池中去.

也就是说:字符串常量池的内容来自于:运行时常量池,程序的动态添加.

3.2String对象的不同创建方式在字符串常量池中的反应

直接赋值:
public static void main(String[] args){
    String s1 = "hello";
    String s2 = "hello";
    System.out.println(s1==s2);//结果是true
}

为什么结果为true,按照上述的讲解,String类是引用对象,按理说所存的地址是不同的.

其主要原因:

  1. 编译时,字节码文件加载,会先将hello字符串加载字符串常量池中去.

  2. 当创建s2时,JVM会先去字符串常量池中匹配是否存在与s2字符串内容相同的对线,如果存在,则直接将该字符串的引用赋值给s2.

使用new创建String类对象
public static void main(String[] args){
    String s3 = new String("world");
    String s4 = new String("world");
    System.out.println(s3==s4);//结果是flase
}

会先讲字符串的内容在常量池中检查,如果常量池中没有,则存入字符串常量池中,

对于new 的对象而言,会在堆中生成一个对象,这个对象是有自己的地址,但是value的内容会指向目标字符串.

图解:
在这里插入图片描述

4.简单了解StringBuffer和StirngBuilder.

4.1介绍StirngBuffer的方法:

StringBuff append(String
str)
在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、
double、float、int、long、Object、String、StringBuff的变量
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取底层保存字符串空间总的大小
void ensureCapacity(int
mininmumCapacity)
扩容
void setCharAt(int index,
char ch)
将index位置的字符设置为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int
fromIndex)
从fromIndex位置开始查找str第一次出现的位置
int lastIndexOf(String str)返回最后一次出现str的位置
int lastIndexOf(String str,
int fromIndex)
从fromIndex位置开始找str最后一次出现的位置
StringBuff insert(int
offset, String str)
在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuffer
deleteCharAt(int index)
删除index位置字符
StringBuffer delete(int
start, int end)
删除[start, end)区间内的字符
StringBuffer replace(int
start, int end, String str)
将[start, end)位置的字符替换为str
String substring(int start)从start开始一直到末尾的字符以String的方式返回
String substring(int
start,int end)
将[start, end)范围内的字符以String的方式返回
StringBuffer reverse()反转字符串
String toString()将所有字符按照String的方式返回

4.2String类与StirngBuffer,StirngBuilder的区别:

  1. String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  2. StringBuffer与StringBuilder大部分功能是相似的 .
  3. StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作

总结:

String类是做题中常用的类,需要着重学习.对于常量池的概念要清楚…
加油加油!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小连~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值