Java中的String数据类型,String类(字符串)详解
目录
- 第一章、String概述
- 1)String是什么
- 2)String长什么样
- 3)String的构造方法(声明方式)
- 第二章、String类的详解
- 1)String底层是什么
- 2)字符串存储的内存原理/字符串常量池(String Constant Pool)
- 3)字符串之间的比较问题
- ①字符串之间的直接比较
- ②字符串拼接完毕后做==比较的问题
- 4)字符串与其他类型的转换
- ①String字符串与基本数据类型的转换
- ②String字符串与包装类型的转换
- 5)String类常用方法
- 第三章、字符串缓冲区StringBuffer和StringBuilder
- 1)字符串缓冲区概述
- 2)StringBuffer和StringBuilder声明方式
- 3)StringBuffer/StringBuilder和String类型之间的转换
- 4)二者的常用方法
第一章、String概述
1)String是什么
①String表示字符串类型,是引用数据类型不是基本数据类型,String是类且是最终类,不能有子类。
②字符串虽然是引用类型属于对象,但是它不是存储在堆空间中,而是存储在方法区中的字符串常量池中。只要我们书写了双引号,数据都会立刻在字符串常量池中保存。
2)String长什么样
使用双引号包裹起来的都是String。
①一个字母被双引号包裹起来的:
“A”
②多个字母被双引号包裹起来的:
“hello daShaGua!”
③中文被双引号包裹起来的:
“你好小可爱”
3)String的构造方法(声明方式)
字符串常用的构造方法:6种
构造方法 | 作用 |
---|---|
String() | 初始化一个新创建的 String 对象,使其表示一个空字符序列。 |
String(String original) | 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。 |
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。 |
String(byte[] bytes, int offset, int length) | 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。 |
String(char[] value) | 分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。 |
String(char[] value, int offset, int count) | 分配一个新的 String,它包含取自字符数组参数一个子数组的字符。 |
Column 1 | Column 2 |
---|---|
centered 文本居中 | right-aligned 文本居右 |
public static void test1(){//String()| 初始化一个新创建的 String 对象,使其表示一个空字符序列。String s1 = ""; //空字符串String s2 = new String(); //空字符串//String(String original)| 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;String s3 = new String(""); //空字符串String s4 = new String("qwer");//String(byte[] bytes) |通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。 byte[] bs = {65,66,97,98};//类型转换:byte[] --> StringString str = new String(bs);System.out.println(str); //"ABab"//String(byte[] bytes, int offset, int length) //通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。 byte[] bs3 = {65,66,67,68,97,98,99,100};//类型转换:byte[] --> StringString str3 = new String(bs3, 2, 5);System.out.println(str3); //"CDab"//String(char[] value) | 初始化一个新创建的 String 对象,使其表示字符数组参数中当前包含的字符序列。char[] cs = {'j','a','v','a'};//类型转换:char[] --> StringString str = new String(cs);System.out.println(str); //"java"//String(char[] value, int offset, int count) | 包含取自字符数组参数一个子数组的字符。 String str1 = new String(cs,0,2);System.out.println(str1); //"ja"}
第二章、String类的详解
1)String底层是什么
查看源码可以发现,String的底层是数组。
jdk1.8及以前String使用的是char数组
jdk1.9及以后使用的是byte数组
因为字符串底层是数组,所以可以遍历字符串
//第一种方式//char charAt(int index):返回指定索引处的 char 值。 String str = "java";for(int i = 0;i <= str.length() - 1;i++){char c = str.charAt(i);System.out.print(c);}
//---------------------------分割------------------------------------------//第二种方式// char[] toCharArray():将此字符串转换为一个新的字符数组。 char[] cs = str.toCharArray();for(int i = 0;i <= cs.length - 1;i++){System.out.print(cs[i]);}
2)字符串存储的内存原理/字符串常量池(String Constant Pool)
①字符串被保存在字符串常量池中,在JDK1.8 字符串常量池在堆中, 运行时常量池在方法区。
②在java中String类型的值是不可改变的,指的是想要改变字符串值时会复用字符串常量池中的地址值。
例如:我们有一个字符串变量s = “a”,然后我们再对s赋值为”b”,我们并没有改变字符串s的值,只是在常量池中新建了一个字符串”b”,然后让s的地址值从指向”a”变成了指向”b”。
String s = "a";
s = "b";//并没有改变S的值,只是在常量池中新建了一个字符串”b”,然后让s从指向”a”变成了指向”b”
③直接赋值会复用字符串常量池中的地址值,new出来的不会复用,而是开辟一个新的空间
//直接赋值会复用字符串常量池中的地址
//它们的地址是一样的,这个就是 String 的复用性。"abc"在常量池中的,并且 s1 和 s2 都指向同一个地方。String s1 = "abc";String s2 = "abc";System.out.println(s1 == s2); //true 比较的是地址值,s1和s2在常量池理指向了同一个地址值System.out.println(s1.equals(s2)); //true 底层重写了toString所以调用equals方法时比较的是内容
//new出来的不会复用,而是开辟一个新的空间 String s3 = new String("abc");System.out.println(s1 == s3); //false new出来的不会复用,而是开辟一个新的空间System.out.println(s1.equals(s3)); //true 底层重写了toString所以调用equals方法时比较的是内容
ps:这里放一个老师的考题
//【问题】:执行完毕下列5行代码,内存中一共有几个对象?//答:4个对象String s1 = "hello"; //1个对象 在常量池中String s2 = "hello"; //不会产生对象String s3 = new String("hello"); //1个对象 在堆中String s4 = new String("helloworld"); //2个对象 一个在堆中,另一个在常量池中String s5 = "helloworld"; //不会产生对象//所以一共是四个对象
3)字符串之间的比较问题
①字符串之间的直接比较
1、==比较的是地址值
2、equals比较的是字符串内容
//直接赋值会复用字符串常量池中的地址
//它们的地址是一样的,这个就是 String 的复用性。"abc"在常量池中的,并且 s1 和 s2 都指向同一个地方。String s1 = "abc";String s2 = "abc";System.out.println(s1 == s2); //true 比较的是地址值,s1和s2在常量池理指向了同一个地址值System.out.println(s1.equals(s2)); //true 底层重写了toString所以调用equals方法时比较的是内容
//new出来的不会复用,而是开辟一个新的空间 String s3 = new String("abc");System.out.println(s1 == s3); //false new出来的不会复用,而是开辟一个新的空间System.out.println(s1.equals(s3)); //true 底层重写了toString所以调用equals方法时比较的是内容
②字符串拼接完毕后做==比较的问题
1、字符串内容做==比较,比较的是地址值,
2、常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量,只要其中有一个是变量,结果就在堆中
3、只有常量池中数据内容进行,比较结果才会为true,有堆参与结果一定为false
4、如果拼接的结果调用intern()方法,返回值就在常量池中
String s1 = "hello"; //s1变量记录的是"hello"常量数据在常量池中的地址String s2 = "world"; //s2变量记录的是"world"常量数据在常量池中的地址String s3 = "helloworld"; //s3变量记录的是"helloworld"常量数据在常量池中的地址System.out.println("hello" + s2 == s3); //常量 + 变量 结果在堆中 堆 == 常量池 falseSystem.out.println(s1 + "world" == s3); //变量 + 常量 结果在堆中 堆 == 常量池 falseSystem.out.println(s1 + s2 == s3); //变量 + 变量 结果在堆中 堆 == 常量池 falseSystem.out.println("hello" + "world" == s3); //常量 + 常量 结果在常量池中 常量池 == 常量池 trueSystem.out.println("================================");System.out.println("hello" + s2 == "hello" + s2); //堆 == 堆 falseSystem.out.println(s1 + "world" == s1 + "world"); //堆 == 堆 falseSystem.out.println(s1 + s2 == s1 + s2); //堆 == 堆 falseSystem.out.println("hello" + "world" == "hello" + "world"); //常量池 == 常量池 trueSystem.out.println("*********************************");/** String intern():返回字符串对象的规范化表示形式。 * 分析:* jvm会去常量池中查找是否存在该字符串常量对象:* 如果存在,则直接返回该常量对象在常量池中的地址信息* 如果不存在,则先在常量池中创建该常量对象,再返回其在常量池中的地址信息*/System.out.println(("hello" + s2).intern() == ("hello" + s2).intern()); //常量池 == 常量池 trueSystem.out.println((s1 + "world").intern() == (s1 + "world").intern()); //常量池 == 常量池 trueSystem.out.println((s1 + s2).intern() == (s1 + s2).intern()); //常量池 == 常量池 trueSystem.out.println(("hello" + "world").intern() == ("hello" + "world").intern()); //常量池 == 常量池 true
4)字符串与其他类型的转换
①String字符串与基本数据类型的转换
1、字符串转为基本类型
String s1 = "123";int i = Integer.parseInt(s1);//类型转换:字符串转为基本类型String s2 = "3.14";double d = Double.parseDouble(s2);
2、基本类型转为字符串
int num = 123;//类型转换:基本类型 -> StringString s1 = num + "";String s2 = Integer.toString(num);String s3 = String.valueOf(num);
②String字符串与包装类型的转换
1、包装类型转为字符串
Integer iObj = Integer.valueOf(123);//类型转换:包装类型 -> 字符串类型String str = iObj.toString();System.out.println(str); //"123"System.out.println(str instanceof String); //true
2、字符串转为包装类型
//类型转换:String -> 包装类型Integer iObj1 = new Integer("123");Double dObj = Double.valueOf("3.14");
5)String类常用方法
String类常用方法:将字符串内容转换为全大写/小写
public static void test5(){/** 将字符串内容转换为全大写/小写* String toLowerCase():使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 * String toUpperCase():使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 */String content = "Today is Friday pm";String newContent = content.toLowerCase();System.out.println(newContent);// 打印结果 today is friday pmnewContent = content.toUpperCase();System.out.println(newContent);// 打印结果 TODAY IS FRIDAY PMSystem.out.println(content);// 打印结果 Today is Friday pm}
String类常用方法:查找字符在字符串中的位置
public static void test4(){/** 得到传入的字符串在原串中首次/最后一次出现的位置:* int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引。 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 注意:从头到尾都比对不上,就返回-1*/String content = "山不在在高,有仙则名。水不在在深,有龙则灵。斯是陋室,惟吾德馨。";int index = content.indexOf("在");//从第0个索引开始找,在第2个索引找到 第一个在System.out.println(index); //2index = content.indexOf("在", 5); //从第5个索引开始找,在第13个索引找到 第一个在System.out.println(index); //13index = content.lastIndexOf("则");//从第0个索引开始找,在第19个索引找到 最后一个则System.out.println(index); //19index = content.lastIndexOf("则",18);//从第18个索引开始向前找,在第8个索引找到 最后一个则System.out.println(index); //8index = content.indexOf("在在");//从第0个索引开始找,在第2个索引找到 第一个 在在System.out.println(index); //2index = content.indexOf("在再");//从第0个索引开始找,没找到 在再 返回-1System.out.println(index); //-1}
String类常用方法:根据参数截取字符串,获得新字符串
/* 截取字符串:String substring(int beginIndex):String substring(int beginIndex, int endIndex):方法的参数存在起始索引和结束索引,绝大多数情况下,都满足含头不含尾的特点*/String content = "唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息。";String newContent = content.substring(4);System.out.println(content);//打印结果 唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息。System.out.println(newContent);//打印结果 唧,木兰当户织。不闻机杼声,惟闻女叹息。newContent = content.substring(3, 5);System.out.println(newContent);//打印结果 唧唧
String类常用方法:切割字符串,返回数组
//根据正则规则切割字符串:String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 //如果匹配不上,则不做任何的切割行为,将原串作为一个整体存入到数组容器中String content = "java is a good lang,java is a nice lang";String regex = ",";String[] strs = content.split(regex);System.out.println(Arrays.toString(strs) + "-->" + strs.length);//打印结果[java is a good lang , java is a nice lang]-->3String[] strs2 = content.split("@");System.out.println(Arrays.toString(strs2) + "-->" + strs2.length);//打印结果[java is a good lang , java is a nice lang]-->1
String类常用方法:拼接字符串的两种方式
//第一种//拼接字符串:String concat(String str):将指定字符串连接到此字符串的结尾。 String s1 = "遥想公瑾当年,";String s2 = "小乔初嫁了。";String result = s1.concat(s2);System.out.println(result);//第二种 System.out.println("谈笑间," + "樯橹灰飞烟灭");
第三章、字符串缓冲区StringBuffer和StringBuilder
1)字符串缓冲区概述
①String是不能更改的,而StringBuffer与StringBuilder则是可变的字符序列。可以看成是高级的String。二者的内部方法是一致的。
②缓冲区就是一个临时空间,它里面可以临时存储数据。缓冲区本身就是一个容器,把需要修改的字符串先存储到字符串缓冲区容器中,在容器中修改完成后存储在字符串常量池中。
③任意类型都可以存储到字符串缓冲区。注意:是将任意数据都转成字符串进行存储;容器对象提供很多对容器中的数据操作的功能,比如添加,删除,修改,查询;
④StringBuffer不提供线程同步,StringBuilder是线程同步的,StringBuilder效率不如StringBuffer,但是StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下会使用 StringBuilder 类。
2)StringBuffer和StringBuilder声明方式
// 默认含有16个字符的容量
StringBuffer sb1 = new StringBuffer();
//含12个字符容量的字符串缓冲区
StringBuffer sb2 = new StringBuffer(12);
// 含16+4的字符串缓冲区,"b cd"为4个字符容量
StringBuffer sb3 = new StringBuffer("b cd");//StringBuilder 同理,就不一一举例了
StringBuilder sb = new StringBuilder("");
3)StringBuffer/StringBuilder和String类型之间的转换
//String类型--》StringBuilder
StringBuilder builder = new StringBuilder("abc");
StringBuilder builder2 = new StringBuilder("abcde");StringBuilder类型--》String
String str = builder.toString();
String str2= new String(builder2);
4)二者的常用方法
①添加
//空参构造StringBuilder sb = new StringBuilder();// 增操作:append和insert//尾部追加数据appendsb.append("abc").append(123).append(3.14).append(true);System.out.println(sb); //缓冲区对象内部数据为 ==> "abc1233.14true"//带参构造StringBuilder sb2 = new StringBuilder("helloworld");System.out.println(sb2);//打印结果 helloworld//在中间某位置插入数据 insertsb2.insert(5, "java");System.out.println(sb2); //打印结果 hellojavaworld
②删除
StringBuilder sb = new StringBuilder("helloabc0world");// 删操作:delete deleteCharAt//删除中间的"abc"数据sb.delete(5, 8);System.out.println(sb);//打印结果 hello0world//删除中间的'0'数据sb.deleteCharAt(5);System.out.println(sb);//打印结果 helloworld
③修改
/*改操作:reversesetCharAtsetLength */String content = "上海自来水来自海上1";//类型转换:String -> StringBuilderStringBuilder sb = new StringBuilder(content);//将sb中的字符串内容进行反转sb.reverse();
//-------------------------------分割--------------------------------StringBuilder sb2 = new StringBuilder("helloworldjavascript");//将sb2对象的容量设置为10个长度==》setLength方法sb2.setLength(10);System.out.println(sb2); //打印结果 "helloworld"//将字符串内容w 改为W==》setCharAt方法sb2.setCharAt(5, 'W');System.out.println(sb2);//打印结果 helloWorld
Java中的String数据类型,String类(字符串)详解相关推荐
- java中object类型_Java常用类object详解
1.Object概述: 类Object是类层次结构的根类.每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法. 2.构造方法详细信息: Object只有一个无参构造方法,因为ob ...
- java中正则表达式Pattern与Matcher类使用详解(find、group)
一.Pattern的使用 这个使用很简单. 1.把正则表达式编译为Pattern对象: 比如: Pattern compile = Pattern.compile("http://([a-z ...
- java中sleep()、wait()相同与不同详解
java中sleep().wait()相同与不同详解 相同 java中Thread#sleep和Object#wait方法都是暂停当前线程,当前线程让出CPU占用.并不存在调用sleep后还占用CPU ...
- Java中的宏变量,宏替换详解。
转载自 Java中的宏变量,宏替换详解. 群友在微信群讨论的一个话题,有点意思,特拿出来分享一下. 输出true false 来看下面这段程序,和群友分享的大致一样. public static vo ...
- java中fmt标签库_jsp fmt标签详解
JSTL标签提供了对国际化(I18N)的支持,它可以根据发出请求的客户端地域的不同来显示不同的语言.同时还提供了格式化数据和日期的方法.实现这些功能需要I18N格式标签库(I18N-capable f ...
- java runtime异常如何解决_成都汇智动力-Java中常见的RunTime异常及异常详解
java.lang.ArithmeticException算术条件异常.譬如:整数除零等.java.lang.ArrayIndexOutOfBoundsException数组索引越界异常.当对数组的索 ...
- Java 中 finally 与 return 的执行顺序详解
java方法是在栈幀中执行,栈幀是线程私有栈的单位,执行方法的线程会为每一个方法分配一小块栈空间来作为该方法执行时的内存空间,栈幀分为三个区域: 1 . 操作数栈,用来保存正在执行的表达式中的操作数, ...
- java 抽象 属性_在java中如何定义一个抽象属性示例详解
前言 本文主要给大家介绍的是在java中定义一个抽象属性的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: Abstract关键字通常被用于类和方法,用来把某些行为的实现委托给 ...
- Java 中的自动装箱和拆箱详解
自动装箱是 Java 编译器在基本类型和它们对应的包装类之间进行的自动转换.例如,将 int 类型转换为 Integer 类型,将 double 类型转换为 Double 型等等.如果转换以相反的方式 ...
- java中的静态变量的作用域_详解JAVA中static的作用
1.深度总结 引用一位网友的话,说的非常好,如果别人问你static的作用:如果你说静态修饰 类的属性 和 类的方法 别人认为你是合格的:如果是说 可以构成 静态代码块,那别人认为你还可以: 如果你说 ...
最新文章
- 数据库的七种传播方式
- php中隐藏和展开文章,手机端第一屏页面文章的展开和隐藏_html/css_WEB-ITnose
- Linux 帐户管理
- SpringBoot使用日志
- 随便选一张扑克牌_扑克牌魔术手法教学,简单易学的纸牌魔术,三分钟让你成为大师...
- 几个改变世界的java工具
- php proc open 返回,PHP proc_open多次打开
- oracle监听器无法启动,提示“错误1067:进程意外终止”
- react native 项目使用 expo 二维码扫描失败
- 计算机主机前后,Win10电脑主机前面的耳机插口没声音怎么办?前置面板插孔没声音...
- 打开Form时报错 FRM-18108:装载下列对象失败 FRM-10102不能附加PLSQL程序库
- 类对象实现红蓝方互殴
- safari html5 自动全屏,javascript – 使用iOS Safari网络浏览器的全屏html5视频
- 什么浏览器最好用,五款浏览器对比那个最好?
- shell编程文档资料
- 【实用教程】本地blast使用及简单python脚本辅助
- Welcome To ZOE's Blog
- 概率导论(极限理论)
- 基于java愤怒的小鸟游戏的设计与实现
- 使用poi实现excel导入导出
热门文章
- 基于RxJava2.0+Retrofit2.0的多线程文件下载实现
- 2021-2027全球及中国激光投影键盘行业研究及十四五规划分析报告
- 国开计算机应用基础模块4实操题答案,国开电大计算机应用基础作业3 模块4 PowerPoint 2010实操题答案...
- html Form表单嵌套
- MindManager中文汉化补丁V2021.20思维导图软件
- python numpy.power()函数的用法
- Python语言的前景、方向、优势、就业情况分析
- 使用AmazeUI做的一个表单案例(验证)
- 假货ht7133症状,输入电压不能超过7v,超过了50Ma,输出电压会跟着输入电压升高而升高,烧后面的零件
- 学习笔记 | 多态案例2-制作饮品