Java基础(十六):String的常用API

目录

  • 一、构造器方法
  • 二、String与字节数组的转换(编码与解码)
    • 1、字符串 --> 字节数组:(编码)
    • 2、字节数组 --> 字符串:(解码)
    • 3、iso-8859-1的特殊用法
    • 4、byte数组的数字表示
  • 三、常用API
    • 1、常用方法
    • 2、查找
    • 3、字符串截取
    • 4、和字符/字符数组相关
    • 5、开头与结尾
    • 6、替换
  • 四、常见算法题
    • 1、模拟一个trim方法,去除字符串两端的空格
    • 2、将一个字符串进行反转。将字符串中指定部分进行反转。比如“ab`cdef`g”反转为”ab`fedc`g”
    • 3、获取一个字符串在另一个字符串中出现的次数。比如:获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数
    • 4、获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"
  • 五、StringBuffer和StringBuilder
    • 1、StringBuffer与StringBuilder的理解
    • 2、StringBuilder、StringBuffer的API
    • 3、效率测试


一、构造器方法

  • public String() :初始化新创建的 String对象,以使其表示空字符序列
  • String(String original): 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本
  • public String(char[] value) :通过当前参数中的字符数组来构造新的String
  • public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的String

举例:

//字面量定义方式:字符串常量对象
String str = "hello";//构造器定义方式:无参构造
String str1 = new String();//构造器定义方式:创建"hello"字符串常量的副本
String str2 = new String("hello");//构造器定义方式:通过字符数组构造
char chars[] = {'a', 'b', 'c','d','e'};     
String str3 = new String(chars); // abcde
String str4 = new String(chars,0,3); // abc

二、String与字节数组的转换(编码与解码)

1、字符串 --> 字节数组:(编码)

  • public byte[] getBytes() :使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
  • public byte[] getBytes(String charsetName) :使用指定的字符集将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组

2、字节数组 --> 字符串:(解码)

  • String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
  • String(byte[],int offset,int length) :用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构造一个字符串对象
  • String(byte[], String charsetName ) 或 new String(byte[], int, int,String charsetName ):解码,按照指定的编码方式进行解码

举例:

byte[] b_gbk = "中".getBytes("gbk");
byte[] b_utf8 = "中".getBytes("utf-8");
byte[] b_iso88591 = "中".getBytes("iso-8859-1");
  • 将返回"中"这个汉字分别在gbk、utf-8、iso-8859-1编码下的字节数组表示
  • 此时b_gbk的长度为2,b_utf8的长度为3,b_iso88591的长度为1
  • 与getBytes()方法相反,可以通过new String(byte[], charsetName)方法用指定的字符集来还原这个"中"字,如:
String s_gbk = new String(b_gbk, "gbk");
String s_utf8 = new String(b_utf8, "utf-8");
String s_iso88591 = new String(b_iso88591, "iso-8859-1");
  • 打印出s_gbk、s_utf8、s_iso88591可以看到,s_gbk和s_utf8都是"中",而s_iso88591是一个乱码
  • 这是因为iso-8859-1的编码表中,根本就没有包含汉字
  • 因此"中".getBytes(“iso-8859-1”)得到的是"?“的字节数组表示
  • 再通过new String(b_iso88591, “iso-8858-1”)还原得到的是”?"

3、iso-8859-1的特殊用法

  • 有时候,为了让中文字符适应某些特殊要求(如http header要求其内容必须是iso-8859-1编码)
  • 可能会通过将中文字符按照字节方式来编码的情况,如:
String s_iso88591 = new String("中".getBytes("utf-8"), "iso-8859-1");
  • 得到的字符串s_iso88591实际上是三个在iso-8859-1中的字符,在将这些字符传送到目的地后,再通过相反的方式,即:
String s_utf8 = new String(s_iso88591.getBytes("iso-8859-1"), "utf-8");
  • 从而得到正确的中文汉字"中",这样就既保证了遵守协议规定,也支持了中文

4、byte数组的数字表示

byte[] b = "中".getBytes("utf-8");
for(int i=0; i<b.length; i++) {System.out.println(b[i]);
}

输出:

-28 
-72 
-83
  • 因为"中"的utf-8编码为三个字节,分别是E4 B8 AD
  • 以E4为例,换成二进制即为:1110 0100
    • 该二进制数将以补码存储在内存中,最高位被视为符号位
    • 因此原码是:1110 0100(补码) -> 1001 1011(反码) -> 1001 1100(原码)
    • 即-(16+8+4)=-28

三、常用API

1、常用方法

  • boolean isEmpty():字符串是否为空
  • int length():返回字符串的长度
  • String concat(xx):拼接
  • boolean equals(Object obj):比较字符串是否相等,区分大小写
  • boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写
  • int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小
  • int compareToIgnoreCase(String other):比较字符串大小,不区分大小写
  • String toLowerCase():将字符串中大写字母转为小写
  • String toUpperCase():将字符串中小写字母转为大写
  • String trim():去掉字符串前后空白符
  • public String intern():结果在常量池中共享
@Test
public void test1(){String s1 = "hello";String s2 = "HellO";System.out.println(s1.equals(s2));System.out.println(s1.equalsIgnoreCase(s2));String s3 = "abcd";String s4 = "adef";System.out.println(s3.compareTo(s4));String s5 = "abcd";String s6 = "aBcd";System.out.println(s5.compareTo(s6));System.out.println(s5.compareToIgnoreCase(s6));String s7 = "张ab";String s8 = "李cd";System.out.println(s7.compareTo(s8));String s9 = " he  llo   ";System.out.println("****" + s9.trim() + "*****");
}

2、查找

  • boolean contains(xx):是否包含xx
  • int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1
  • int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
  • int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1
  • int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
@Test
public void test2(){String s1 = "教育尚硅谷教育";System.out.println(s1.contains("硅谷")); // trueSystem.out.println(s1.indexOf("教育")); // 0System.out.println(s1.indexOf("教育",1)); // 5System.out.println(s1.lastIndexOf("教育")); // 5System.out.println(s1.lastIndexOf("教育",4)); // 0
}

3、字符串截取

  • String substring(int beginIndex) :返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串
  • String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串
@Test
public void test3(){String s1 = "教育尚硅谷教育";System.out.println(s1.substring(2)); // 尚硅谷教育System.out.println(s1.substring(2,5));//[2,5) // 尚硅谷
}

4、和字符/字符数组相关

  • char charAt(index):返回[index]位置的字符
  • char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
  • static String valueOf(char[] data) :返回指定数组中表示该字符序列的 String
  • static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String
@Test
public void test4(){String s1 = "教育尚硅谷教育";System.out.println(s1.charAt(2)); // 尚// valueOf和copyValueOf源码一模一样的,就是用char数组new String(char[] ch)String s2 = String.valueOf(new char[]{'a', 'b', 'c'}); // abcString s3 = String.copyValueOf(new char[]{'a', 'b', 'c'}); // abc
}

5、开头与结尾

  • boolean startsWith(xx):测试此字符串是否以指定的前缀开始
  • boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
  • boolean endsWith(xx):测试此字符串是否以指定的后缀结束
@Test
public void test5(){String s1 = "教育尚硅谷教育";System.out.println(s1.startsWith("教育a")); // falseSystem.out.println(s1.startsWith("教育",5)); // true
}

6、替换

  • String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 不支持正则
  • String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串
  • String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
  • String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串
@Test
public void test6(){String s1 = "hello";String s2 = s1.replace('l', 'w');System.out.println(s1); // helloSystem.out.println(s2); // hewwoString s3 = s1.replace("ll", "wwww");System.out.println(s3); // hewwwwo
}

四、常见算法题

1、模拟一个trim方法,去除字符串两端的空格

思路:查看字符串前缀后缀是否存在“ ”,去除后继续判断

public static String trimStr(String str) {while (str.startsWith(" ") || str.endsWith(" ")) {if (str.startsWith(" ")) {str = str.substring(1);}if (str.endsWith(" ")) {str = str.substring(0, str.length() - 1);}}return str;
}

2、将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反转为”abfedcg”

方法一思路:字符串转换为字符数组,从指定角标到结束角标,互换数据

public static String reversalStr(String str, int fromIndex, int toIndex) {char[] charArray = str.toCharArray();for (int i = fromIndex, j = toIndex; i < j; i++, j--) {char temp = charArray[i];charArray[i] = charArray[j];charArray[j] = temp;}return new String(charArray);
}

方法二思路:截取前中后三个字符串,中是需要反转的,从新拼接,拼接中字符串时候,从后开始拼接

public static String reversalStr2(String str, int fromIndex, int toIndex) {String strReturn = str.substring(0, fromIndex);for (int i = toIndex; i >= fromIndex; i--) {strReturn += str.charAt(i);}strReturn += str.substring(toIndex + 1);return strReturn;
}

3、获取一个字符串在另一个字符串中出现的次数。比如:获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数

思路:获取字符首次出现的角标,然后从出现的位置继续向后找

public static int getCount(String str, String subStr) {int count = 0;int index = str.indexOf(subStr);while (index != -1) {index = str.indexOf(subStr, index + subStr.length());count++;}return count;
}

4、获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = “cvhellobnm”

思路:从小字符串下手,通过不同长度截取

public static String getMaxStr(String str1, String str2) {for (int i = 0; i < str2.length(); i++) {for (int x = 0, y = str2.length() - i - x; y <= str2.length(); x++, y++) {String substring = str2.substring(x, y);if (str1.contains(substring)) {return substring;}}}return null;
}

五、StringBuffer和StringBuilder

  • 因为String对象是不可变对象,虽然可以共享常量对象,但是对于频繁字符串的修改和拼接操作,效率极低,空间消耗也比较高
  • 因此,JDK又在java.lang包提供了可变字符序列StringBuffer和StringBuilder类型

1、StringBuffer与StringBuilder的理解

  • java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明
  • 可以对字符串内容进行增删,此时不会产生新的对象
//情况1:
String s = new String("我喜欢学习"); 
//情况2:
StringBuffer buffer = new StringBuffer("我喜欢学习"); 
buffer.append("数学"); 

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

  • StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样
  • 区分String、StringBuffer、StringBuilder
    • String:不可变的字符序列; 底层使用char[]数组存储(JDK8.0中)
    • StringBuffer:可变的字符序列;线程安全(方法有synchronized修饰),效率低;底层使用char[]数组存储 (JDK8.0中)
    • StringBuilder:可变的字符序列; jdk1.5引入,线程不安全的,效率高;底层使用char[]数组存储(JDK8.0中)

2、StringBuilder、StringBuffer的API

StringBuilder、StringBuffer的API是完全一致的,并且很多方法与String相同

常用API

  • StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接
  • StringBuffer delete(int start, int end):删除[start,end)之间字符
  • StringBuffer deleteCharAt(int index):删除[index]位置字符
  • StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str
  • void setCharAt(int index, char c):替换[index]位置字符
  • char charAt(int index):查找指定index位置上的字符
  • StringBuffer insert(int index, xx):在[index]位置插入xx
  • int length():返回存储的字符数据的长度
  • StringBuffer reverse():反转
@Test
public void test1(){StringBuilder  sBuilder = new StringBuilder();sBuilder.append("abc").append("123").append("def"); //方法链的调用System.out.println(sBuilder); StringBuilder sBuilder = new StringBuilder("hello");sBuilder.insert(2, "中");System.out.println(sBuilder); // he中lloStringBuilder sBuilder1 = sBuilder.reverse();System.out.println("反转字符串:" + sBuilder); // oll中ehSystem.out.println("反转返回字符串:" + sBuilder1); // oll中ehSystem.out.println("反转字符串是否与返回字符串是同一个对象:" + (sBuilder == sBuilder1)); // trueSystem.out.println("字符串长度:" + sBuilder.length()); //实际存储的字符的个数  // 6
}

其它API

  • 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的最后一次出现下标
  • String substring(int start):截取当前字符序列[start,最后]
  • String substring(int start, int end):截取当前字符序列[start,end)
  • String toString():返回此序列中数据的字符串表示形式
  • void setLength(int newLength) :设置当前字符序列长度为newLength

3、效率测试

测试String、StringBuffer、StringBuilder在操作数据方面的效率

@Test
public void test4() {//初始设置long startTime = 0L;long endTime = 0L;String text = "";StringBuffer buffer = new StringBuffer("");StringBuilder builder = new StringBuilder("");//开始对比startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {buffer.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuffer的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {builder.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuilder的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {text = text + i;}endTime = System.currentTimeMillis();System.out.println("String的执行时间:" + (endTime - startTime));
}

输出结果:

StringBuffer的执行时间:14
StringBuilder的执行时间:2
String的执行时间:264

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

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

相关文章

Java版Flink使用指南——从RabbitMQ中队列中接入消息流

大纲 创建RabbitMQ队列新建工程新增依赖编码设置数据源配置读取、处理数据完整代码 打包、上传和运行任务测试 工程代码 在《Java版Flink使用指南——安装Flink和使用IntelliJ制作任务包》一文中&#xff0c;我们完成了第一个小型Demo的编写。例子中的数据是代码预先指定的。而…

判断对象能否回收的两种方法,以及JVM引用

判断对象能否回收的两种方法&#xff1a;引用计数算法&#xff0c;可达性分析算法 引用计数算法&#xff1a;给对象添加一个引用计数器&#xff0c;当该对象被其它对象引用时计数加一&#xff0c;引用失效时计数减一&#xff0c;计数为0时&#xff0c;可以回收。 特点&#xf…

自动驾驶SLAM又一开源巅峰之作!深挖时间一致性,精准构建超清地图

论文标题&#xff1a; DTCLMapper: Dual Temporal Consistent Learning for Vectorized HD Map Construction 论文作者&#xff1a; Siyu Li, Jiacheng Lin, Hao Shi, Jiaming Zhang, Song Wang, You Yao, Zhiyong Li, Kailun Yang 导读&#xff1a; 本文介绍了一种用于自动…

突发!马斯克3140亿参数Grok开源!Grok原理大公开!

BIG NEWS: 全球最大开源大模型&#xff01;马斯克Grok-1参数量3410亿&#xff0c;正式开源!!! 说到做到&#xff0c;马斯克xAI的Grok&#xff0c;果然如期开源了&#xff01; 就在刚刚&#xff0c;马斯克的AI创企xAI正式发布了此前备受期待大模型Grok-1&#xff0c;其参数量达…

硅纪元视角 | 虚拟神经科学的突破:AI「赛博老鼠」诞生

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

企业需要什么样的MES?

MES&#xff08;英文全称&#xff1a;Manufacturing Execution System&#xff09;&#xff0c;即制造执行系统&#xff0c;是面向车间生产的管理系统。它位于上层计划管理系统&#xff08;如ERP&#xff09;与底层工业控制&#xff08;如PCS层&#xff09;之间&#xff0c;是制…

【Linux】:服务器用户的登陆、删除、密码修改

用Xshell登录云服务器。 1.登录云服务器 先打开Xshell。弹出的界面点。 在终端上输入命令ssh usernameip_address&#xff0c;其中username为要登录的用户名&#xff0c;ip_address为Linux系统的IP地址或主机名。 然后输入密码进行登录。 具体如下&#xff1a; 找到新建会话…

Windows与time.windows.com同步time出错(手把手操作)

今天我来针对Windows讲解Time同步 时间问题 计算机的时间不同&#xff0c;过快或者过慢。&#xff08;可以和自己的手机时间进行对比&#xff0c;手机的时间进行同步的频率会比计算机更快&#xff0c;因此更精准&#xff09;计算机time过快和过慢&#xff0c;会导致使用过程中…

想实现随时随地远程访问?解析可道云teamOS内网穿透功能

在数字化时代&#xff0c;无论是个人还是企业&#xff0c;都面临着数据共享与远程访问的迫切需求。 比如我有时会需要在家中加班&#xff0c;急需访问公司内网中的某个关键文件。 然而&#xff0c;由于公网与内网的天然隔阂&#xff0c;这些需求往往难以实现。这时&#xff0c…

代码随想录 链表章节总结

移除链表元素 && 设计链表 学会设置虚拟头结点 翻转链表 leetcode 206 https://leetcode.cn/problems/reverse-linked-list/description/ 方法一&#xff1a;非递归新开链表 头插法&#xff1a;创建一个新的链表&#xff0c;遍历旧链表&#xff0c;按顺序在新链表使…

AIGC | 在机器学习工作站安装NVIDIA CUDA® 并行计算平台和编程模型

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 0x02.初识与安装 CUDA 并行计算平台和编程模型 什么是 CUDA? CUDA&#xff08;Compute Unified Device Architecture&#xff09;是英伟达&#xff08;NVIDIA&#xff09;推出的并行计算平台和编…

idea提交代码或更新代码一直提示token然后登陆失败无法提交或者更新代码

最近因为换了电脑需要对开发环境做配置&#xff0c; 遇到了这个问题&#xff0c; 应该是因为我们用到了gitlab&#xff0c;默认的最新的idea会有gitlab插件 强制录入gitlab的token&#xff0c;如果gitlab不支持token的验证那么问题就来了 &#xff0c; 不管怎么操作都无法提交或…

Spring MVC深入理解之源码实现

1、SpringMVC的理解 1&#xff09;谈谈对Spring MVC的了解 MVC 是模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;其核心思想是通过将业务逻辑、数据、显示分离来组织代码。 Model&#xff1a;数据模型&#xff0c;JavaBean的类&#xff0c;用来进行数据封装…

单链表详解(2)

三、函数定义 查找节点 //查找结点 SLTNode* SLTNodeFind(SLTNode* phead, SLTDataType x) {assert(phead);SLTNode* pcur phead;while (pcur){if (pcur->data x){return pcur;}pcur pcur->next;}return NULL; } 查找节点我们是通过看数据域来查找的&#xff0c;查…

【MySQL05】【 undo 日志】

文章目录 一、前言二、undo 日志&#xff08;回滚日志&#xff09;1. 事务 id2. undo 日志格式2.1 INSERT 对应的 undo 日志2.2 DELETE 对应的 undo 日志2.3 UPDATE 对应的 undo 日志2.3.1 不更新主键2.3.2 更新主键 2.3 增删改操作对二级索引的影响2.4 roll_pointer 3. FIL_PA…

layui项目中的layui.define、layui.config以及layui.use的使用

第一步:创建一个layuiTest项目&#xff0c;结构如下 第二步&#xff1a;新建一个test.js,利用layui.define定义一个模块test,并向外暴露该模块&#xff0c;该模块里面有两个方法method1和method2. 第三步&#xff1a;新建一个test.html&#xff0c;在该页面引入layui.js&#x…

neo4j 图数据库:Cypher 查询语言、医学知识图谱

neo4j 图数据库&#xff1a;Cypher 查询语言、医学知识图谱 Cypher 查询语言创建数据查询数据查询并返回所有节点查询并返回所有带有特定标签的节点查询特定属性的节点及其所有关系和关系的另一端节点查询从名为“小明”的节点到名为“小红”的节点的路径 更新数据更新一个节点…

python爬虫和用腾讯云API接口进行翻译并存入excel,通过本机的Windows任务计划程序定时运行Python脚本!

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a;定时爬取外网的某个页面&#xff0c;并将需要的部分翻译为中文存入excel 接下了的&#xff0c;没学过的最好看一下 基本爬虫的学习 【爬虫】requests 结合 BeautifulSoup抓取网页数据_requests beauti…

Vue CoreVideoPlayer 一款基于 vue.js 的轻量级、优秀的视频播放器组件

大家好,我是程序视点的小二哥!今天小二哥给大家推荐一款非常优秀的视频播放组件 效果欣赏 介绍 Vue-CoreVideoPlayer 一款基于vue.js的轻量级的视频播放器插件。 采用Adobd XD进行UI设计&#xff0c;支持移动端适配,不仅功能强大&#xff0c;颜值也是超一流&#xff01; Vue-…

第一次构建一个对话机器人流程解析(二)

1. 问答机器人的组成-基于知识图谱的搜索 在教育场景下&#xff0c;若学生有关于学习内容的提问&#xff0c;或业务层面的提问&#xff0c;则要求问答机器人的回答必须精准&#xff0c;来满足业务的要求因此需要通过知识图谱来快速检索&#xff0c;所提内容的相关信息&#xf…