JAVA的字符串这篇讲清楚了

news/2024/9/24 20:16:18/文章来源:https://www.cnblogs.com/ivanlee717/p/18429920

JAVA_String

从概念上讲,JAVA字符串就是Unicode序列。例如"Java\u2122"由5个UNICODE字符J,a,v,a和™组成。Java没有内置和字符串类型,而是试用java标准库中提供的一个预定义类,很自然地叫做了string

子串substring

String subStr = str.substring(beginIndex);

这里 beginIndex 指的是子字符串开始位置的索引(包括该位置的字符),结束位置是字符串的末尾。

String str = "hello";
System.out.println(str.substring(0,3)); //'hel'

重载版本:

String subStr = str.substring(beginIndex, endIndex);

在这个版本中,beginIndexendIndex 分别指定了子字符串开始和结束的位置。注意 endIndex 不包含在子字符串内,即子字符串包含索引为 beginIndexendIndex - 1 的字符。

image-20240924164847577

拼接

与绝大多数语言一样,Java允许使用+号连接两个字符串

String str = "ivanlee";
String str1 = "regina";
System.out.println(str+str1);//ivanleeregina

当将一个字符串与一个非字符串的值进行拼接时,后者回转换成字符串,且任何一个java对象都可以转换成字符串。

String str = "ivanlee";
int no = 7;
System.out.println(str+no);//ivanlee7

在java11当中,还提供了repeat方法

String str = "ivanlee".repeat(3);//ivanleeivanleeivanlee

字符串不可变

String类没有提供任何方法来修改字符串的某个字符。如果希望将字符串内容修改,不能直接对字符串进行修改,只能对字符串进行读取和拼接,比如'ivanlee'把最后的ee改成aa只能是

String str = "ivanlee";
String newstr = str.substring(0,5) + "aa";

这样不能修改字符串有一个很大的优点就是编译器可以让字符串共享。

想象各个字符串存放在一个公共存储池里,字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串和复制的字符串共享相同的字符。

字符串相等

equals()equalsIgnoreCase()函数分别比较区分大小写的字符串以及忽视大小写的字符串。

String str = "ivanlee";
String newstr = "iVanlee";
System.out.println(newstr.equals(str)); //false
System.out.println(str.equalsIgnoreCase(newstr)); //true

不要使用运算符检测两个字符串,这个运算符只能够确定两个字符串是否存放在同一个位置。所以相同的字符串副本可能会放在不同的位置上。如果虚拟机总是共享相等的字符串,则可以使用运算符检测字符串是否相等。但实际上只有字符串字面量会共享。而+或者substring等操作得到的字符串并不共享。因此,千万不要使用==来测试是否相等。

String s1 = "abc"; // 字符串字面量,s1 指向字符串池中的 "abc"
String s2 = "abc"; // s2 也指向字符串池中的 "abc",s1 == s2 返回 trueString s3 = new String("abc"); // 创建了一个新的对象,不在字符串池中
String s4 = "abc";             // s4 指向字符串池中的 "abc"
// s3 和 s4 内容相同,但不是同一个对象,因此 s3 == s4 返回 falseString s5 = "ab" + "c";       // 字符串连接,结果仍然会在字符串池中查找或创建 "abc"
String s6 = "abc";            // s6 指向字符串池中的 "abc"
// s5 和 s6 都指向字符串池中的 "abc",因此 s5 == s6 返回 trueString s7 = "abc".substring(0, 3); // 使用 substring 方法,结果不在字符串池中
String s8 = "abc";                  // s8 指向字符串池中的 "abc"

image-20240924175224957

在 Java 8 及之前的版本中,substring 方法返回的字符串不会自动放入字符串池中,因此 s7s8 尽管内容相同,但它们不是同一个对象。因此 s7 == s8 将返回 false。从 Java 9 开始,JEP 282(String Concatenation Optimization)引入了优化,使得某些字符串操作(包括 substring 方法)的结果在某些情况下可能会被放入字符串池中,但这取决于 JVM 的实现细节。

码点和代码单元

在Java中,“码点”(code point)和“代码单元”(code unit)是与Unicode字符编码相关的术语。它们之间的关系主要体现在Java如何处理Unicode字符上。
码点指的是Unicode标准中定义的唯一标识符,用于唯一地标识一个字符。Unicode标准覆盖了所有的字符集,从ASCII到各种语言的文字符号,甚至到数学符号和表情符号。每一个字符都有一个唯一的码点,这个码点是一个整数值。Unicode码点范围从U+0000到U+10FFFF,共包含了超过110万个可能的字符。
代码单元是指在特定编码方案中表示一个字符所需的位数。在Java中,字符是以16位(两个字节)的Unicode代码单元存储的,这是因为Java的 char 类型是16位的无符号整数。

Java中的字符表示:
基本多文种平面(BMP)字符:这些字符的码点范围是从U+0000到U+FFFF,可以直接用一个 char 类型表示。Java中的大多数字符都属于这一类。
代理项(Surrogate Pairs):对于超出BMP范围的字符(即码点大于U+FFFF),需要使用一对代理项来表示。这对代理项由一个高位代理项(high surrogate)和一个低位代理项(low surrogate)组成,每个代理项也是一个 char 类型。
高位代理项的码点范围是U+D800到U+DBFF。
低位代理项的码点范围是U+DC00到U+DFFF。

// BMP字符可以直接用一个char表示
char c1 = 'A'; // 码点 U+0041
System.out.println(c1);// 非BMP字符需要两个char表示(代理项)
String emoji = "😀"; // 码点 U+1F600
System.out.println(emoji.codePointCount(0, emoji.length())); // 输出 1,因为只有一个码点// 查看具体的码点值
int codePoint = emoji.codePointAt(0);
System.out.println(codePoint); // 输出 U+1F600 的值// 获取具体的代码单元序列
for (int i = 0; i < emoji.length(); i++) {char codeUnit = emoji.charAt(i);System.out.println("Code unit: " + codeUnit);
}
Code point count: 1
Code unit: ᘔ
Code unit: ᗩ
Code point value: 128512

java.lang.string

  • char charAt(int index)
    返回给定位置的代码单元。除非对底层的代码单元感兴趣,否则不需要调用这个方法。

  • int codePointAt(int index) 返回从给定位置开始的码点。

  • int offsetByCodePoints(int startIndex, int cpCount)
    返回从 startIndex 码点开始,cpCount个码点后的码点索引。

  • int compareTo(String other)
    按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符申位于other 之后,返回一个正数;如果两个字符串相等,返回0。

  • IntStream codePoints()
    将这个字符串的码点作为一个流返回。调用toArray将它们放在一个数组中。

  • new String(int[] codePoints, int offset, int count)
    用数组中从 offset 开始的count个码点构造一个字符串。

  • boolean isEmpty( )

    boolean isBlank()
    如果字符串为空或者由空白符组成,返回true。

  • boolean startsWith(String prefix) boolean endsWith(String suffix)
    如果字符串以prefix开头或以 suffix或结尾,则返回 true。

  • int indexof(String str)

  • int index0f(String str, int fromIndex)

  • int indexOf(int cp)

  • int index0f(int cp, int fromIndex)
    返回与字符串 str或码点cp相等的第一个子串的开始位置。从索引日或 froaIndex开始
    匹配。如果 str或 cp不在字符串中,则返回-1。

  • int lastIndexOf(String str)

  • int lastIndexOf(String str, int fromIndex)

  • int lastindexOf(int cp)

  • int lastindexOf(int cp, int fromIndex)
    返回与字符串 str或码点 cp相等的最后一个子串的开始位置。从字符串末尾或 froaInde
    开始匹配。如果 str或cp不在字符串中,则返回-1。

  • int length() 返回字符串代码单元的个数。

  • int codePointCount(int startIndex,int endIndex)
    返回 startIndex到endIndex-1之间的码点个数。

  • String replace(CharSequence oldString, CharSequence newString)
    返回一个新字符串,这是用 nestring替换原始字符串中与oldString匹配的所有子串得到的。可以用String或StringBuilder对象作为CharSequence 参数。

  • String substring(int beginIndex)

  • String substring(int beginIndex, int endIndex)
    返回一个新字符串,这个字符串包含原始字符串中从beginIndex到字符串末尾或endIndex-1的所有代码单元。

  • String toLowerCase()
    String toUpperCase()
    返回一个新字符串,这个字符串包含原始字符串中的所有字符,不过将原始字符串中的大写字母改为小写,或者将原始字符串中的小写字母改成大写母。String strip()

  • String stripLeading()
    String stripTrailing()
    返回一个新字符串,这个字符串要删除原始字符串头部和尾部或者只是头部或尾部的空白符。要使用这些方法,而不要使用古老的trim方法删除小于等于U+0020的字符。

  • String join(CharSequence delimiter, charSequence...elements)
    返回一个新字符串,用给定的定界符连接所有元素。

    构建字符串

    有些时候,需要由较短的字符串构建字符串。例如:按键或者文件中的单词。如果采用字符串拼接的方式来达到这个目的,效率会很低。每次拼接字符串时,都会构建一个新的string对象,又耗时又浪费空间。使用StringBuilder类来避免这个问题。

    StringBuilder builder = new StringBuilder();
    //当每次需要添加另外一部分时,就调用append方法
    builder.append('i');
    builder.append("vanlee");
    //字符串构建完成时,调用tostring方法就得到一个string对象,其中包含了构建器中的字符队列
    String completedString = builder.toString();//builder: ivanlee
    //completedString: ivanlee
    
  • StringBuilder()
    构造一个空的字符串构建器。

  • int length()
    返回构建器或缓冲器中的代码单元个数。

  • StringBuilder append(String str)
    追加一个字符串并返回this。

  • StringBuilder append(char c)
    追加一个代码单元并返回this。

  • StringBuilder appendCodePoint(int cp)
    追加一个码点,将它转换为一个或两个代码单元并返回 this。

  • void setcharAt(int i,char c)
    将第i个代码单元设置为c。

  • StringBuilder insert(int offset, String str)
    在 ofset 位置插入一个字符串并返回 this。

  • StringBuilder insert(int offset, char c)
    在 ofset 位置插人一个代码单元并返回 this。

  • StringBuilder delete(int startIndex, int endIndex)
    删除从 startIndex到endIndex-1的代码单元并返回 this。

  • String toString()
    返回一个字符串,其数据与构建器或缓冲器内容相同

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/802999.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

任务4:制作二维码

该二维码链接到游戏“植物大战僵尸”,寓教于乐。 提升趣味性和互动性的同时,学生们参与到课堂当中,发挥主体作用,感受到自然界植物的多样性,对土壤的作用有了更深刻的理解。

封装的练习题目1

1.使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心 情,名字;方法包括:叫,跑。 要求: 1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问 2)限定心情只能有“心情好”和“心情不好”两种情况,如果无效输入进行提示, 默认…

五款免费可视化工具全解析:选择你的最佳搭档

1. 山海鲸可视化 介绍: 山海鲸可视化是一款免费的国产可视化报表软件,与许多其他宣传免费的软件不同,山海鲸的报表功能完全免费并且没有任何限制,就连网站管理后台这个功能也是免费的。同时山海鲸可视化还提供了种类丰富的可视化图表、三维模型、模板可供使用,软件采用点击…

408OS_PV操作大题总结

咸鱼今年压了读者写者问题,前几年没考过。死锁的四个条件是:禁止抢占(no preemption):系统资源不能被强制从一个线程中退出。 持有和等待(hold and wait):一个线程在等待时持有并发资源。持有并发资源并还等待其它资源,也就是吃着碗里的望着锅里的。 互斥(mutual exc…

2024.9.24 思维导图与PDF

哈哈哈终于有我也用过的东西啦~Xmind一款打工人用了都说好的软件(#.#) 【知识小课堂1】不同款式的思维导图:【知识小课堂2】PDF转换器! 1、PDF(便携式文档格式),这种文件格式与操作系统平台无关 —— PDF文件不管是在Windows还是别的操作系统中都是通用的。 2、这一特点使它…

如何设计一个伪无埋点的框架?

主要基于无埋点的缺点,来设计一个伪无埋点的框架,使得业务既可以拥有无埋点的特性,又能满足业务的数据分析需求本文同步发布于公众号:移动开发那些事如何设计一个伪无埋点的框架 在前面的文章:Android无埋点技术概览 中提到传统的无埋点有几大缺点:埋点字段有限,没有办法…

吴恩达机器学习课程 笔记4 分类 逻辑回归

逻辑回归 机器学习中的逻辑回归(Logistic Regression)是一种广泛使用的分类算法,尽管它的名字中包含“回归”这个词,但实际上它主要用于解决分类问题,特别是二分类问题。逻辑回归模型可以用来预测某一类事件发生的概率,例如预测用户是否会点击广告、病人是否患有某种疾病…

设计模式之中介模式(三分钟学会一个设计模式)

中介模式(Mediator)又称之为调停模式。mediator [ˈmiːdieɪtə(r)] n. 调停者;斡旋者;解决纷争的人(或机构); 本意就是解决纠纷的中间人它是面向对象六大原则中最少知道原则的一个典型应用。(关于面向对象六大原则,可看前文:https://www.cnblogs.com/jilodream/p/535351…

Large Vision Model

LVM https://yutongbai.com/lvm.html https://zhuanlan.zhihu.com/p/671423679Large Vision Model(简称LVM)是一种纯粹基于视觉数据进行训练和推理的大型模型,其特点在于无需涉及任何自然语言输入或输出。该模型的提出源自一篇由UC Berkeley的三位计算机视觉专家联合撰写的论…

2024 天池云原生编程挑战赛决赛名单出炉,冠军来自中山大学、昆仑数智战队

9 月 20 日,2024 天池云原生编程挑战赛决赛答辩完美落幕,12 支进入决赛的团队用精彩的答辩,为历时 3 个月的大赛画下了圆满的句号。其中,来自中山大学的陈泓仰以及来自昆仑数智的冉旭欣、沈鑫糠、武鹏鹏,以出色的方案、创新的优化思路、过硬的技术实力分获赛道一和赛道二的…