【Java原理探索】带你实战使用String的功能特性 | Java开发实战

简介: 【Java原理探索】带你实战使用String的功能特性 | Java开发实战

前提回顾

java.lang.String类用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描 述,如:"abc"。

  • 该类由final关键字修饰,表示该类不能被继承
  • 从jdk1.9开始该类的底层不使用char[]来存储数据,而是改成 byte[]加上编码标记,从而节约了一 些空间
  • 该类描述的字符串内容是个常量不可更改,因此可以被共享使用

如: String str1 = “abc”;  其中"abc"这个字符串是个常量不可改变。


image.png

public static void main(String[] args) {        
        String s1="abc";        
        String s2="abc";        
        System.out.println(s1==s2); //true 比较地址 abc存在常量池 
}
复制代码



常量池概念


String类描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能(创建对象以分配内存消耗资源过大)且节省了空间。



常用的构造方法


方法声明 功能介绍
String() 使用无参方式构造对象得到空字符序列 ,“” 表示空字符串
String(byte[] bytes, int offset, int length) 使用bytes数组中下标从offset位置开始的length个字节来构造对象
String(byte[] bytes) 使用bytes数组中的所有内容构造对象
String(char[] value, int offset, int count) 使用value数组中下标从offset位置开始的count个字符来构 造对象
String(char[] value) 使用value数组中的所有内容构造对象
String(String original) 根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本




方法代码案例

public static void main(String[] args) {
 //下面代码会创建几个对象,分别存放在哪里
 String s1 = "abc";  // 1个对象 存在常量池
 String s2 = new String("abc");  //2个对象  "abc"在常量池  new的对象在堆区(堆区存abc的副本) s2指向堆区
 String s3="hello";
 String s4="hello";
 String s5=new String("hello");
 String s6=new String("hello");
 System.out.println(s3==s4);         //true
 System.out.println(s3.equals(s4));  //true
 System.out.println(s5==s6);         //false
 System.out.println(s5.equals(s6));  //true
 System.out.println(s3==s5);         //false
 System.out.println(s3.equals(s5));  //true
 //常量有优化机制,变量没有
 String a1="abcd";
 String a2="ab"+"cd";       // 常量优化机制   "abcd"
 System.out.println(a1==a2);//比较地址true
 String a3="ab";
 String a4=a3+"cd";          //没有优化机制,如同new一个String
 System.out.println(a3==a4);//比较地址 false
}
复制代码




常用的成员方法

方法声明 功能介绍
String toString() 返回字符串本身,重写Object toString()方法
byte[] getBytes() 将当前字符串内容转换为byte数组并返回,先将字符串拆分为字符,再将字符转byte
char[] toCharArray() 用于将当前字符串内容转换为char数组并返回
char charAt(int index) 方法charAt用于返回字符串指定位置的字符。
int length() 返回字符串字符序列的长度
boolean isEmpty() 判断字符串是否为空
int compareTo(String anotherString) 用于比较调用对象和参数对象的大小关系
int compareToIgnoreCase(String str) 不考虑大小写,也就是'a'和'A'是相等的关系
String concat(String str) 用于实现字符串的拼接
boolean contains(CharSequence s) 用于判断当前字符串是否包含参数指定的内容,String实现类CharSequence接口
String toLowerCase() 返回字符串的小写形式 //常量 转换后不会改变原值
String toUpperCase() 返回字符串的大写形式
String trim() 返回去掉前导和后继空白的字符串
boolean startsWith(String prefix) 判断字符串是否以参数字符串开头
boolean startsWith(String prefix, int toffset) boolean endsWith(String suffix)
boolean endsWith(String suffix) 判断字符串是否以参数字符串结尾
boolean equals(Object anObject) 用于比较字符串内容是否相等并返回
int hashCode() 获取调用对象的哈希码值
boolean equalsIgnoreCase(String anotherString) 用于比较字符串内容是否相等并返回,不考虑大小写, 如:'A'和'a'是相等
int indexOf(int ch) 用于返回当前字符串中参数ch指定的字符第一次出现的下标
int indexOf(int ch, int fromIndex) 用于从fromIndex位置开始查找ch指定的字符
int indexOf(String str) 在字符串中检索str返回其第一次出现的位置,若找不到 返回-1,正向查找
int indexOf(String str, int fromIndex) 表示从字符串的fromIndex位置开始检索str第一次出现 的位置
int lastIndexOf(int ch) 用于返回参数ch指定的字符最后一次出现的下标
int lastIndexOf(int ch, int fromIndex) 用于从fromIndex位置开始查找ch指定字符出现的下标
int lastIndexOf(String str) 返回str指定字符串最后一次出现的下标 ,反向查找
int lastIndexOf(String str, int fromIndex) 用于从fromIndex位置开始反向搜索的第一次出现的下 标。
String substring(int beginIndex, int endIndex) 返回字符串中从**下标beginIndex(包括)开始到 endIndex(不包括)**结束的子字符串
String substring(int beginIndex) 返回字符串中从下标beginIndex(包括)开始到字符串结尾 的子字符串





正则表达式的概念


正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查 找、替换等操作。该字符串通常使用^运算符作为开头标志,使用$运算符作为结尾标志,当然也可以省略。



正则表达式的规则


正则表达式 说明
[abc] 可以出现a、b、c中任意一个字符
[^abc] 可以出现任何字符,除了a、b、c的任意字符
[a-z] 可以出现a、b、c、……、z中的任意一个字符
[a-zA-Z0-9] 可以出现az、AZ、0~9中任意一个字符
. 任意一个字符(通常不包含换行符)
\d 任意一个数字字符,相当于[0-9]
\D 任意一个非数字字符
\s 空白字符,相当于[\t\n\x0B\f\r]
\S 非空白字符
\w 任意一个单词字符,相当于[a-zA-Z_0-9]
\W 任意一个非单词字符
X? 表示X可以出现一次或一次也没有,也就是0 ~ 1次
X* 表示X可以出现零次或多次,也就是0 ~ n次
X+ 表示X可以出现一次或多次,也就是1 ~ n次
X{n} 表示X可以出现恰好 n 次
X{n,} 表示X可以出现至少 n 次,也就是>=n次
X{n,m} 表示X可以出现至少 n 次,但是不超过 m 次,也就是>=n并且<=m次

用 () 进行分组,无实际意义



正则表达式相关的方法


方法名称 方法说明
boolean matches(String regex) 判断当前正在调用的字符串是否匹配参数指定的正则表达式规则。
String[] split(String regex) 参数regex为正则表达式,以regex所表示的字符串为分隔 符,将字符串拆分成字符串数组
String replace(char oldChar, char newChar) 使用参数newChar替换此字符串中出现的所有参数 oldChar
String replaceFirst(String regex, String replacement) 替换此字符串匹配给定的正则表达式的第一个子字符串
String replaceAll(String regex, String replacement) 将字符串中匹配正则表达式regex的字符串替换成replacement




可变字符串类


基本概念


  • 由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串 时,只能单独申请和存储,此时会造成内存空间的浪费。
  • 为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序 列可以改变的字符串,如:"ab"。
  • StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。
  • StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。



StringBuilder类常用的构造方法


方法名称 功能介绍
StringBuilder() 使用无参方式构造对象,容量为16
StringBuilder(int capacity) 根据参数指定的容量来构造对象,容量为参数指定大小
StringBuilder(String str) 根据参数指定的字符串来构造对象,容量为:16+字符串长度



StringBuilder类常用的成员方法
方法名称 功能介绍
int capacity() 用于返回调用对象的容量
int length() 用于返回字符串的长度,也就是字符的个数
StringBuilder insert(int offset, String str) 插入字符串并返回调用对象的引用,就是自己
StringBuilder append(String str) 追加字符串
StringBuilder deleteCharAt(int index) 将当前字符串中下标为index位置的单个字符 删除
StringBuilder delete(int start,int end) 删除字符串
StringBuilder replace(int start,int end, String str) 替换字符串
StringBuilder reverse() 字符串反转
StringBuilder setCharAt(int index,char char) 修改下标为index的字符为char


注意 作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值



返回值的设计


  • StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this


  • 这些方法在对StringBuilder所封装的字符序列进行改变后又返回了该对象的引用。基于这样设计的目的在于可以连续调用



扩容算法源码分析


  • *当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量 2+2


  • 底层采用byte数组来存放所有的字符内容




相关文章
|
10天前
|
缓存 监控 Java
Java虚拟机(JVM)性能调优实战指南
在追求软件开发卓越的征途中,Java虚拟机(JVM)性能调优是一个不可或缺的环节。本文将通过具体的数据和案例,深入探讨JVM性能调优的理论基础与实践技巧,旨在为广大Java开发者提供一套系统化的性能优化方案。文章首先剖析了JVM内存管理机制的工作原理,然后通过对比分析不同垃圾收集器的适用场景及性能表现,为读者揭示了选择合适垃圾回收策略的数据支持。接下来,结合线程管理和JIT编译优化等高级话题,文章详细阐述了如何利用现代JVM提供的丰富工具进行问题诊断和性能监控。最后,通过实际案例分析,展示了性能调优过程中可能遇到的挑战及应对策略,确保读者能够将理论运用于实践,有效提升Java应用的性能。 【
45 10
|
9天前
|
分布式计算 DataWorks Java
DataWorks操作报错合集之使用ODPS Tunnel Upload功能时,遇到报错:Java 堆内存不足,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
13天前
|
存储 监控 Java
揭秘Java虚拟机:探索JVM的工作原理与性能优化
本文深入探讨了Java虚拟机(JVM)的核心机制,从类加载到垃圾回收,再到即时编译技术,揭示了这些复杂过程如何共同作用于Java程序的性能表现。通过分析现代JVM的内存管理策略和性能监控工具,文章提供了实用的调优建议,帮助开发者有效提升Java应用的性能。
31 3
|
1天前
|
监控 Java 开发者
深入理解Java并发编程:线程池的原理与实践
【5月更文挑战第85天】 在现代Java应用开发中,高效地处理并发任务是提升性能和响应能力的关键。线程池作为一种管理线程的机制,其合理使用能够显著减少资源消耗并优化系统吞吐量。本文将详细探讨线程池的核心原理,包括其内部工作机制、优势以及如何在Java中正确实现和使用线程池。通过理论分析和实例演示,我们将揭示线程池对提升Java应用性能的重要性,并给出实践中的最佳策略。
|
1天前
|
监控 算法 Java
Java中的垃圾收集机制:原理与优化实践
在Java的内存管理领域中,垃圾收集(Garbage Collection, GC)扮演着至关重要的角色。本文将深入探讨Java垃圾收集的核心概念、工作机制以及性能调优策略。通过具体案例分析,我们揭示不同垃圾收集器的行为模式并讨论如何根据应用场景做出合理选择。针对JVM监控和诊断工具的使用也将被详细介绍,旨在为读者提供一套系统的解决方案,以实现Java应用的性能优化。
|
3天前
|
Java Unix Linux
Java跨平台运行的底层原理是什么
Java跨平台运行的底层原理是什么?
|
存储 Java
【Java 虚拟机原理】线程栈 | 栈帧 | 局部变量表 | 反汇编字节码文件 | Java 虚拟机指令手册 | 程序计数器
【Java 虚拟机原理】线程栈 | 栈帧 | 局部变量表 | 反汇编字节码文件 | Java 虚拟机指令手册 | 程序计数器
112 0
【Java 虚拟机原理】线程栈 | 栈帧 | 局部变量表 | 反汇编字节码文件 | Java 虚拟机指令手册 | 程序计数器
|
14天前
|
Java 调度
Java线程的六种状态
Java线程有六种状态: 初始(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)、终止(TERMINATED)。
34 1
|
1天前
|
安全 Java 数据处理
Java并发编程:线程同步与协作的深度解析
在探索Java并发编程的海洋中,线程同步与协作的灯塔指引着航向。本文将深入挖掘线程同步机制的核心原理,揭示锁、条件变量等工具如何确保数据的一致性和线程间有序的通信。通过案例分析,我们将解码高效并发模式背后的设计哲学,并探讨现代Java并发库如何简化复杂的同步任务。跟随文章的步伐,您将获得提升多线程应用性能与可靠性的关键技能。 【7月更文挑战第24天】
13 5
|
1天前
|
Java
如何使用jstack命令查看Java进程的线程栈
如何使用jstack命令查看Java进程的线程栈?
10 2