必须知道的String知识点
1.String 类型的概述
Java中String就是Unicode字符序列,例如,字符串“Java\u2122”由5个Unicode字符J、a、v、a和 ™ 组成。不像C/C++中,字符串只是字符数组,Java中字符串String是一个java.lang包中的类。
但是,在Java中String和普通的类不一样,是一个特殊的类:
- String可以直接使用双引号""进行赋值,而不用调用构造函数。
- '+'可以拼接两个字符串,但是其他对象不能使用'+'。
- String是不可变的,也就是说,String对象一旦创建就不能被修改。例如,toUpperCase() 方法创建并返回一个新字符串,而不是修改原理字符串的内容。
String类型的常用方法总结:
// 长度
int length() // 返回字符串的长度
boolean isEmpty() // 判断长度是否==0
// 比较
boolean equals(String another) // Java中不能使用 '==' 或者 '!=' 来比较两个字符串
boolean equalsIgnoreCase(String another)
int compareTo(String another) // 返回 0 如果字符串相同;< 0 如果字典序小于another;否则 > 0
int compareToIgnoreCase(String another)
boolean startsWith(String another)
boolean startsWith(String another, int fromIndex) // 在fromIndex位置开始
boolean endsWith(String another)
// 检索 & 索引下标
int indexOf(String search)
int indexOf(String search, int fromIndex)
int indexOf(int character)
int indexOf(int character, int fromIndex)
int lastIndexOf(String search)
int lastIndexOf(String search, int fromIndex)
int lastIndexOf(int character)
int lastIndexOf(int character, int fromIndex)
// 截取字符串的字符或一部分字符串(子串)
char charAt(int index) // 下标从 0 到 length - 1
String substring(int fromIndex)
String substring(int fromIndex, int endIndex) // 包前不包后
// 根据原字符串创建一个新字符串或字符数组
String toLowerCase()
String toUpperCase()
String trim() // 返回一个移除前后空白的新字符串
String replace(char oldChar, char newChar) // 返回一个替换后的字符串
String concat(String another) // 字符串拼接
char[] toCharArray() // 返回一个字符串数组
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) // 复制到 dst 字符数组中
// 静态方法,将基本类型转换为字符串
static String valueOf(type arg) // type可以是基本类型或者字符数组
// 静态方法,将字符串进行格式化输出
static String format(String formattingString, Object... args) // 类似于printf()
// 正则表达式
boolean matches(String regex)
String replaceFirst(String regex, String replacement)
String replaceAll(String regex, String replacement)
String[] split(String regex)
String[] split(String regex, int limit)
静态方法 String.format()
这个方法用来输出一个格式化的字符串,类似于 C 系列的 printf() 函数。例如,
String.format("%.1f", 1.234); // 返回字符串 "1.2"
String.format() 可以非常方便地用来输出一个简单格式的字符串(比如,在 toStirng() 方法中使用)。对于复杂的字符串,使用StringBuffer/StringBuilder加一个Formatter。
2. String 一个特殊的类
因为程序会频繁的使用 String 类型,String 类型在Java中是很特殊的。自然,为了计算性能和存储效率,String 的性能很关键。为了提高提高语言的性能,Java设计者们在面向对象语言中,保留了基本数据类型,而不是一切都是对象。基本数据类型存储在调用栈上,从而占用更少的存储空间,以及更容易维护。而对象实例存储在堆上,需要更复杂的内存管理和更多的存储空间。
为了更好地性能,Java 的 String 被设计成介于基本数据类型和普通类之间的一个特殊类型。Stirng 的特性包括:
- 用于基本数据类型操作的'+',被 String 重载用来拼接两个字符串。出于软件工程的考虑,Java 不支持操作符的重载。在支持操作符重载的语言中,比如 C++ ,甚至可以将 '+' 重载用来执行减法运算,这会使得代码难以阅读。Java 中 '+' 只被内部重载用于字符串拼接。'+' 并不能用于任意两个对象中,比如 Points 或者 Circles。
String 有两种创建方式:直接赋值 或者 通过 new 关键字创建(这种方式不推荐,也不常见)
举个例子:String str1 = "Java is Hot"; // 隐式地通过 String 字面量创建
String str2 = new String("I'm cool"); // 显式地使用 new 创建
在第一条语句中,str1 被申明为一个 String 类型引用,并被 String 字面量 "Java is Hot" 初始化。在第二条语句中,str2 被申明为一个 String 类型引用,并通过 new 关键字构造的 "I'm cool" String 对象初始化。
Stirng 字面量存储在常量池中,相同内容的字符串是共享的,只会存储一份。通过 new 创建的 String 对象存储在堆上,相同内容的字符串不会共享。
2.1 String 字面量 VS String 对象
如上所述,有两种方式构造 String :通过 String 字面量隐式地构造,或者通过 new 显式地创建。比如:
String s1 = "Hello"; // String 字面量
String s2 = "Hello"; // String 字面量
String s3 = s1; // 相同的引用
String s4 = new String("Hello"); // String 对象
String s5 = new String("Hello"); // String 对象
Java 提供一个特别的机制,字符串常量池,来保存 String 字面量。如果两个 String 字面量内容相同,它们将会在字符串常量池中共享。频繁使用的字符串将会通过这种方式持久地保存。另一方面,通过new 创建的 String 对象被保存在堆中。每个存储在堆上的 String 对象,就像其他对象一样,拥有独立的存储地址。堆上的存储地址不会共享,即使两个 String 对象内容相同。
可以使用 String 类的 equals() 方法比较两个字符串的内容。也可以使用 '==' 来比较两个对象的引用(或者叫指针)。看看下面的代码:
s1 == s1; // true, 相同的引用
s1 == s2; // true, s1 和 s2 在常量池中共享
s1 == s3; // true, s3 被赋值为 s1 的引用
s1.equals(s3); // true, 内容相同
s1 == s4; // false, 对象引用不同
s1.equals(s4); // true, 内容
s4 == s5; // false, 堆上的引用不同
s4.equals(s5); // true, 内容相同
重点:
- 在上面的例子中,通过'=='比较两个 String 对象的引用,说明了字符串存储在常量池和存储在堆上的区别。在程序中,使用 (str1 == str2) 来比较两个字符串的内容是逻辑上的错误。
- String 直接赋值的内容将存储在字符串常量池中。不推荐使用 new 去创建一个堆上的字符串对象。
2.2 String 的不可变特性
因为字符串在常量池中是共享的,Java 的 String 被设计成不可变的。也就是说,一旦 String 被创建,它的内容就不能被修改。否则,其他共享内容的 Stirng 引用将会被无法预料变化影响。类似于 toUpperCase() 的方法就可能修改 String 对象的内容,而实际上它将返回一个新创建的 String 对象,原本的 String 对象引用会被释放,一旦没有引用了,就将会被GC。
因为 String 是不可变的,频繁修改 String 的效率很低(这将创建大量的字符串,并占用内存空间)。比如下面这段代码:
// 效率低的代码
String str = "Hello";
for (int i = 1; i < 1000; ++i) {
str = str + i;
}
如果需要频繁修改字符串,可以考虑使用 StringBuffer 或者 StringBuilder。
3. StringBuffer & StringBuilder
如前所述,字符串是不可变的,因为存储在字符串常量池中的字面量是共享的。修改其中一个字符串的内容,将会对其他共享的字符串产生副作用。
JDK 提供了两个类来支持可变的字符串:StringBuffer 和 StringBuilder(都在核心包 java.lang 中)。StringBuffer 和 StringBuilder 对象跟其他普通对象一样,存储在堆上,不会共享,因此修改它们不会对其他对象产生副作用。
StringBuilder 类是在JDK 1.5中引入的。它基本上与 StringBuffer 一致,除了它是线程不安全的以外。对于单线程的程序来说,StringBuilder 因为没有同步的开销,效率会更高。
必须知道的String知识点的更多相关文章
- Javascript:必须知道的Javascript知识点之“单线程事件驱动”
heiboard: Javascript:必须知道的Javascript知识点之“单线程事件驱动”
- 深入理解.net - 4.你必须知道的String
为什么要单独写string,主要是它太常用了,同时又太特殊了,特殊到CLR对它的处理都和其它对象不一样.简直可以称为VIP用户啊.本文并不是一篇介绍如何使用string的文章,而是旨在阐述string ...
- 【源码分析】你必须知道的string.IsNullOrEmpty && string.IsNullOrWhiteSpace
写在前面 之前自信撸码时踩了一次小坑,代码如下: private static void AppServer_NewMessageReceived(WebSocketSession session, ...
- 你必须知道的MySQL知识点
什么是索引 索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构(掌握) 数据结构可视化 前置知识:树的高度越低查询效率越高 二叉树:不能自平衡,极端情况出现倾斜,查询效率和链表类似 红黑 ...
- 《jQuery风暴》第2章 必须知道的JavaScript知识
第2章 必须知道的JavaScript知识 JavaScript是jQuery应用的基础,掌握JavaScript这门语言是使用jQuery的基础条件.本章不会全面细致的讲解JavaScript的全部 ...
- 必须知道的ADO.NET 数据库连接池
http://www.cnblogs.com/liuhaorain/archive/2012/02/19/2353110.html 题外话 通过前几章的学习,不知道大家对ADO.NET有一定的了解了没 ...
- C语言学习书籍推荐《你必须知道的495个C语言问题》
萨米特 (Steve summit) (作者), 孙云 (译者), 朱群英 (译者) 下载地址:点我 <你必须知道的495个C语言问题>以问答的形式组织内容,讨论了学习或使用C语言的过程中 ...
- 《你必须知道的.NET》读书笔记一:小OO有大智慧
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.对象 (1)出生:系统首先会在内存中分配一定的存储空间,然后初始化其附加成员,调用构造函数执行初 ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
随机推荐
- PS命令和kill命令
名称:ps使用权限:所有使用者使用方式:ps [options] [--help]说明:显示瞬间行程 (process) 的动态参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义-A ...
- xadmin自定义菜单、增加功能、富文本编辑器
xadmin功能:https://www.cnblogs.com/derek1184405959/p/8682250.html#blogTitle7
- JVM(二) 栈内存结构
栈内存是描述java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表.操作数栈.动态链接.返回出口等信息.每一个方法从调用直至执行完成的过程,就对应 ...
- 使用speedtest-cli测量服务器带宽
使用speedtest-cli测量服务器带宽,这个是python写的工具,很方便,只需要在服务器端安装即可. 1.安装python-pip # yum install python-pip –y 2. ...
- K-th occurrence HDU - 6704 (SA, 主席树)
大意: 给定串$s$, $q$个询问$(l,r,k)$, 求子串$s[l,r]$的第$k$次出现位置. 本来是个简单签到题, 可惜比赛的时候还没学$SA$...... 好亏啊 相同的子串在$SA$中是 ...
- 修改mysql远程数据库链接密码(转)
原文:https://blog.csdn.net/jianjiao7869/article/details/81029171 原来root用户有两个,一个只允许localhost登陆,一个可运行所有用 ...
- jquery滚动到顶部
<script> $.fn.scrollTo = function (options) { var defaults = { toT: , //滚动目标位置 durTime: , //过渡 ...
- 滤波器算法(1)-卡尔曼滤波小车附带题目与MATLAB程序
1 简介 由卡尔曼这个学者提出的最佳线性滤波器,单纯时域维度即可实现[无需进行频域变换] 2 思路 由上一时刻的最佳估计值XKE_P预测①当前时刻预测值Pxv 与 ②当前时刻的测量值Mxv 进行联立计 ...
- 在论坛中出现的比较难的sql问题:19(row_number函数 行转列、sql语句记流水)
原文:在论坛中出现的比较难的sql问题:19(row_number函数 行转列.sql语句记流水) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记 ...
- Authentication failed for "http://xxxxxx"
1.配置用户信息 git config --global user.name [username] git config --global user.email [email] 2.查询用户信息 ...