IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 字符串String类(Java语言) -> 正文阅读

[Java知识库]字符串String类(Java语言)

前言

我们在学习C语言,对于字符串是没有专门的类型进行定义的,而Java语言是有专门的类型定义字符串的——String,这篇博客将会详细的介绍Java中对于字符串类型的讲解。

创建字符串

常见的构造String的方式

public class TestDemo2 {
    public static void main(String[] args) {
        //方式一
        String str = "hello";
        //方式二
        //调用构造方法进行构造对象
        String str2 = new String("hello");
        //方式三
        char[] chars = {'a', 'b', 'c'};
        String str3 = new String(chars);
        System.out.println(str3);
    }
}

注意事项:

  • “hello”这样的字符串字面值常量,类型也是String。
  • String也是引用类型。

引用类型:

引用类似于 C 语言中的指针, 只是在栈上开辟了一小块内存空间保存一个地址。但是引用和指针又不太相同, 指针能进行各种数字运算(指针+1)之类的, 但是引用不能, 这是一种 “没那么灵活” 的指针。
另外, 也可以把引用想象成一个标签, “贴” 到一个对象上。一个对象可以贴一个标签, 也可以贴多个。如果一个对象上面一个标签都没有, 那么这个对象就会被 JVM 当做垃圾对象回收掉。
Java 中数组, String, 以及自定义的类都是引用类型。

因此,String str = “hello”;这样的代码内存布局如下:
在这里插入图片描述
因此,String str1 = “Hello”;String str2 = str1;这样的代码内存布局如下:
在这里插入图片描述
那么问题来了,如果修改str1,那么str2会不会随之改变呢?

str1 = "world";
System.out.println(str2);
// 执行结果
Hello

实际上,str1 = “world”,并不算真正的“修改”字符串,而是让str1这个引用指向一个新的String对象。
在这里插入图片描述
因此,我们知道了,传引用不一定就能改变对应的值,而是要从底层的出发,看这个引用的作用是什么,又干了些什么。

字符串比较相等

引用比较

如果现在有两个int型变量,判断其相等可以使用==完成。

int x = 10 ;
int y = 10 ;
System.out.println(x == y); 
// 执行结果
true

那么如果是String类对象使用==呢?
代码1

String str1 = "Hello";
String str2 = "Hello"; 
System.out.println(str1 == str2); 
// 执行结果
true 

代码2

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false

为什么会出现这种情况呢?
对于代码1内存布局是这样的:
在这里插入图片描述
我们发现,str1 和 str2 是指向同一个对象的。此时如 “Hello” 这样的字符串常量是在字符串常量池中。

字符串常量池:
如 “Hello” 这样的字符串字面值常量,也是需要一定的内存空间来存储的。这样的常量具有一个特点,就是不需要修改(常量嘛)。所以如果代码中有多个地方引用都需要使用 “Hello” 的话,就直接引用到常量池的这个位置就行了,而没必要把 “Hello” 在内存中存储两次。也就是说字符串常量值是为了提高效率而存在的。

而对于代码2内存布局是这样的:
在这里插入图片描述
通过String str1 = new String(“Hello”); 这样的方式创建的String对象相当于再堆上另外开辟了空间来存储"Hello"的内容, 也就是内存中存在两份"Hello"。

内容比较

上面的String使用==比较并不是在比较字符串内容,而是比较两个引用是否是指向同一个对象。那么如何比较字符串中的内容呢?很简单,我们可以通过String类提供的equals方法进行比较。举个例子:

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// System.out.println(str2.equals(str1)); // 或者这样写也行
// 执行结果
true

如此我们就可以比较字符串的内容了,当然equals()方法有注意事项的。举一个例子:

String str = new String("Hello");
// 方式一
System.out.println(str.equals("Hello"));
// 方式二
System.out.println("Hello".equals(str));

从本质上来看,这两种方法都可以,但是使用方式一会有一个问题,当str为null时,方式一会抛出空指针异常,因此我们在使用时需要注意,使用equals()方法的对象会不会为null。

理解字符串不可变

字符串是一种不可变对象。它的内容不可改变。
String 类的内部实现也是基于 char[] 来实现的,但是 String 类并没有提供 set 方法之类的来修改内部的字符数组。
我们来看这样一组代码:

String str = "hello" ; 
str = str + " world" ; 
str += "!!!" ; 
System.out.println(str); 
// 执行结果
hello world!!!

形如 += 这样的操作,表面上好像是修改了字符串,其实不是。内存变化如下:
首先为“hello”开辟一块空间,由str指向“hello”对象。
在这里插入图片描述
其次为“world”开辟一块空间,再将“hello”和“world”连起来,再为“hello world”开辟一块空间,最后由str指向“hello world”。
在这里插入图片描述
下面的也是如此,因此我们知道:+= 之后 str 打印的结果却是变了,但是不是 String 对象本身发生改变,而是 str 引用到了其他的对象。所以在编程时,我们不能出现下面类似的代码,否则效率会很低。

String str = "hello" ; 
for(int x = 0; x < 1000; x++) {
    str += x ; 
}
System.out.println(str);

字符,字节与字符串

字符与字符串

字符串内部包含一个字符数组,String 可以和 char[] 相互转换。
代码1:

public static void main(String[] args) {
        char[] val = {'a', 'b', 'c'};
        String str = new String(val);
        System.out.println(str);
    }

作用:将字符数组中的所有内容变成字符串。
解释:String(char val[ ])构造方法,将val[ ]数组的内容变成字符串。
结果:在这里插入图片描述

代码2:

public static void main(String[] args) {
        char[] val = {'a', 'b', 'c','d','e'};
        String str = new String(val,1,3);
        System.out.println(str);
    }

作用:将部分字符数组中的内容变成字符串。
解释:String(char value[ ],int offset, int count)构造方法,将val[ ]数组从下标为offset的位置到后面count个元素变成字符串。
结果:在这里插入图片描述
代码3:

public static void main(String[] args) {
        String str = "hello";
        char ch = str.charAt(2);
        System.out.println(ch);
    }

作用:获得指定索引位置的字符,索引从0开始。
解释:charAt(int index)方法,获得字符串中第index下标的字符。
结果:在这里插入图片描述
代码4:

public static void main(String[] args) {
        String str = "hello";
        char[] chars = str.toCharArray();
        System.out.println(Arrays.toString(chars));
    }

作用:将字符串变成字符数组返回。
解释:toCharArray()方法,将调用的字符串变成字符数组,并返回该数组。
结果:在这里插入图片描述

字节与字符串

代码1:

public static void main(String[] args) {
        byte[] bytes = {97, 98, 99, 100};
        String str = new String(bytes);
        System.out.println(str);
    }

作用:将字节数组变成字符串
解释:String(byte bytes[ ])构造方法,将bytes[ ]字节数组变成对应的字符串。
结果:
在这里插入图片描述
代码2:

public static void main(String[] args) {
        byte[] bytes = {97, 98, 99, 100};
        String str = new String(bytes,1,3);
        System.out.println(str);
    }

作用:将部分字节数组中的内容变成字符串。
解释:String(byte bytes[ ],int offset,int length)构造方法,将val[ ]数组从下标为offset的位置到后面count个元素变成字符串。
结果:
在这里插入图片描述代码3:

public static void main(String[] args) {
        String str2 = "abcd";
        byte[] bytes = str2.getBytes();
        System.out.println(Arrays.toString(bytes));
    }

作用:将字符串以字节数组的形式返回。
解释:getBytes()方法,将调用的字符串变成字节数组,并返回该数组。
结果:
在这里插入图片描述

小结

  • byte[ ]是把String按照一个字节一个字节的方式处理,这种适合在网络传输,数据存储这样的场景下使用。更适合针对二进制数据来操作。
  • char[ ]是把String按照一个字符一个字符的方式处理,更适合针对文本数据来操作,尤其是包含中文的时候。

字符串常见的操作

字符串的比较

上面使用过String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断。除了这个方法之外,String类还提供有如下的比较操作:

NO.方法名称类型描述
1.public boolean equals(Object anObject)普通区分大小写的比较
2.public boolean equalsIgnoreCase(String anotherString)普通不区分大小写
3.public int compareTo(String anotherString)普通比较两个字符串大小关系

代码示例:

String str1 = "hello" ; 
String str2 = "Hello" ; 
System.out.println(str1.equals(str2)); // false 
System.out.println(str1.equalsIgnoreCase(str2)); // true

在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内容:

  1. 相等:返回0。
  2. 小于:返回内容小于0。
  3. 大于:返回内容大于0。

代码示例:

System.out.println("A".compareTo("a")); // -32 
System.out.println("a".compareTo("A")); // 32 
System.out.println("A".compareTo("A")); // 0 
System.out.println("AB".compareTo("AC")); // -1 
System.out.println("刘".compareTo("杨")); //小于0

compareTo()是一个可以区分大小关系的方法,是String方法里是一个非常重要的方法。字符串的比较大小规则,总结成三个字 “字典序” 相当于判定两个字符串在一本词典的前面还是后面。先比较第一个字符的大小(根据 unicode 的值来判定),如果不分胜负,就依次比较后面的内容。

字符串查找

从一个完整的字符串之中可以判断指定内容是否存在,对于查找方法有如下定义:

NO.方法名称类型描述
1.public boolean contains(Char Sequence)普通判断一个子字符串是否存在
2.public int indexOf(String str)普通从头开始找指定字符串的位置,查到了返回位置的开始索引,如果查不到返回-1
3.public int lndexOf(String str,int fromIndex)普通从指定位置开始查找子字符串位置
4.public int lastlndexOf(String str)普通由后向前查找子字符串位置
5.public int lastlndexOf(String str,int fromIndex)普通从指定位置由后向前查找子字符串
6.public boolean startsWith(String prefix)普通判断是否以指定字符串开头
7.public boolean startsWith(String prefix,int toffset)普通从指定位置开始判断是否以指定字符串开头
6.public boolean endsWith(String suffix)普通判断是否以指定字符串结尾

代码示例:
字符串查找,最好用最方便的就是contains()。

String str = "helloworld" ; 
System.out.println(str.contains("world")); // true 

代码示例:
使用indexOf()方法进行位置查找。

String str = "helloworld" ; 
System.out.println(str.indexOf("world")); // 5,w开始的索引
System.out.println(str.indexOf("bit")); // -1,没有查到
if (str.indexOf("hello") != -1) { 
 System.out.println("可以查到指定字符串!"); 
} 

注意事项:
使用indexOf()需要注意的是,如果内容重复,它只能返回查找的第一个位置。例如:

String str = "helloworld" ; 
System.out.println(str.indexOf("l")); // 2 
System.out.println(str.indexOf("l",5)); // 8 
System.out.println(str.lastIndexOf("l")); // 8 

代码示例:
判断开头和结尾

String str = "**@@helloworld!!" ; 
System.out.println(str.startsWith("**")); // true 
System.out.println(str.startsWith("@@",2)); // ture 
System.out.println(str.endsWith("!!")); // true

字符串替换

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

NO.方法名称类型描述
1.public String replaceAll(String regex,String repalcement)普通替换所有的指定内容
2.public String replaceFirst(String regex,String repalcement)普通替换首个内容

代码示例:
字符串的替换处理。

String str = "helloworld" ; 
System.out.println(str.replaceAll("l", "_")); //he__owor_d
System.out.println(str.replaceFirst("l", "_")); //he_loworld

注意事项:
由于字符串是不可变对象,替换不修改当前字符串, 而是产生一个新的字符串。

字符串拆分

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

NO.方法名称类型描述
1.public String[] split(String regex)普通将字符串全部拆分
2.public String[] split(String regex,int limit)普通将字符串部分拆分,该数组长度就是limit极限

代码示例:
实现字符串的拆分处理。

String str = "hello world hello bit" ; 
String[] result = str.split(" ") ; // 按照空格拆分
for(String s: result) { 
 System.out.println(s); 
} 

代码示例:
字符串的部分拆分。

String str = "hello world hello bit" ; 
String[] result = str.split(" ",2) ; 
for(String s: result) { 
 System.out.println(s); 
} 

另外,拆分是特别常用的操作。有些特殊字符作为分割符可能无法正确切分,需要加上转义。
代码示例:
拆分IP地址。

String str = "192.168.1.1" ; 
String[] result = str.split("\\.") ; 
for(String s: result) { 
 System.out.println(s); 
} 

代码示例:
多次拆分。

String str = "name=zhangsan&age=18" ; 
String[] result = str.split("&") ; 
for (int i = 0; i < result.length; i++) { 
 String[] temp = result[i].split("=") ; 
 System.out.println(temp[0]+" = "+temp[1]); 
} 

字符串截取

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

NO.方法名称类型描述
1.public String substring(int beginIndex)普通从指定索引截取到结尾
2.public String substring(int beginIndex,int endIndex)普通截取部分内容

代码示例:
观察字符串截取。

String str = "helloworld" ; 
System.out.println(str.substring(5)); //world
System.out.println(str.substring(0, 5)); //hello

注意事项:

  1. 索引从0开始。
  2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标。

其他操作方法

NO.方法名称类型描述
1.public String trim ()普通去掉字符串中的左右空格,保留中间空格
2.public String toUpperCase()普通字符串转大写
3.public String toLowerCase()普通字符串转小写
4.public String concat(String str)普通截取部分内容
5.public int length()普通取得字符串长度
6.public boolean isEmpty普通判断是否为空字符串,但不是null,而是长度为0

代码示例:
观察trim()方法的使用

String str = " hello world " ; 
System.out.println("["+str+"]"); 
System.out.println("["+str.trim()+"]"); 

在这里插入图片描述
trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等)。
代码示例:
大小写转化

String str = " hello%$$%@#$%world 哈哈哈 " ; 
System.out.println(str.toUpperCase()); 
System.out.println(str.toLowerCase());

在这里插入图片描述
这两个方法只转换字母。
代码示例:
字符串length()

String str = " hello%$$%@#$%world 哈哈哈 " ; 
System.out.println(str.length());

在这里插入图片描述
注意:数组长度使用数组名称.length属性,而String中使用的是length()方法。
好了,关于String类的相关知识点绝大部分都在这里了,如果对你有所帮助,别忘了点赞,有意见或者是想法,欢迎各位评论和私信,谢谢大家的支持!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:16:53  更:2022-01-04 13:17:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:44:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码