3.字符串【Java温故系列】

参考自–《Java技术核心卷1》

字符串

从概念上看,Java字符串就是Unicode字符序列。

Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,String.每个用双引号括起来的字符串都是String类的一个实例:

String e = "";   //空字符串
String s = "String";

1 子串

String类的substring方法可以从一个较大的字符串提取出一个子串:

String s = "Hello";
String sz = s.substring(0,3);   //sz = "Hel"

创建了一个由字符"Hel"组成的字符串。

substring方法的第二个参数是不想复制的第一个位置。

上例中要复制的字符为0、1、2(从0~2,包括0和2)位置上的字符,直到3为止,但不包含3.

substring的工作方式有一个优点:容易计算子串的长度。字符串s.substring(a,b)的长度即为b-a.


2 拼接

Java允许使用+号连接(拼接)两个字符串。如:

String s1 = "Hello";
String s2 = " World";
String s = s1 + s2; //s的值为  "Hello World"

当将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串。

如果需要把多个字符串放到一起,用一个定界符分隔,可以使用静态join方法:

String all = String.join("/","S","M","L"); // all 等于 "S/M/L"(/可为其他符号)

3 不可变字符串

String类没有提供可用于修改字符串的方法,由于不能修改Java字符串中的字符,所以Java文档中将String类对象称为不可变字符串

如果要修改字符串,只能“拆”“接”进行:如"Hello"修改成"Help"

String s1 = "Hello";
String s2 = s1.substring(0,3)+"p"; // s2 等于 "Help"

如同数字3永远是数字3一样,字符串"Hello"永远包含字符H,e,l,l,o的代码单元序列,而不能修改其中的任何一个字符。当然,可以修改字符串变量,让它引用另外一个新的字符串。

不可变字符串有一个优点:编译器可以让字符串共享

为了弄清具体的工作方式,可以想象将各种字符串存放在公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量 , 原始字符串与复制的字符串共享相同的字符。修改字符串变量即使它指向新的字符串。

由于Java具有垃圾回收机制,不存在内存遗漏问题。


4 检测字符串是否相等

可以使用equals方法检测两个字符串是否相等。对于表达式:

s.equals(t);

如果字符串s与字符串t相等,则返回true;否则,返回false。s与t可以是字符串变量,也可以是字符串常量

要想检测两个字符串是否相等,而不区分大小写,可以使用equalsIgnoreCase方法:

"Hello".equalsIgnoreCase("hello"); //true

:一定不要使用 == 运算符检测两个字符是否相等!

这个运算符只能够确定两个字符串是否放置在同一个位置上。当然,如果字符串放置在同一个位置上,它们必然相等。但是,完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。

如果虚拟机始终将相同的字符串共享,就可以使用运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。因此,千万不要使用运算符测试字符串的相等性,以免在程序中出现糟糕的bug。从表面上看,这种bug很像随机产生的间歇性错误。


5 空串和Null串

空串""是长度为0的字符串。可以这样判断一个字符串是否为空:

if(str.length()==0)

if(str.equals(""))

空串是一个Java对象,有自己的串长度(0)和内容(空)。不过String变量还可以存放一个特殊的值,名为null,这表示目前没有任何对象与该变量关联。

要检查一个字符串是否为null,可以这样判断:

if(str == null)

有时需要检查一个字符串既不是null也不为空串:

if(str != null && str.length() != 0)

首先要检查str不为null(如果在一个null值上调用方法,会出现错误)。


6 码点与代码单元

Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示的Unicode码点的代码单元。大多数的常用的Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

length方法返回的即为采用UTF-16编码表示的给定字符串所需要的代码单元数量。

String s = "Hello";
int n = s.length(); // n 等于 5

要想得到实际的长度,即码点数量,可以调用:

int nCount = s.codePointCount(0,s.length());

调用s.charAt(n)将返回字符串位置n的代码单元,n介于0~s.length()-1之间。如:

char first = s.charAt(0);  // first为s字符串的第一个字符,即'H'

要想得到第i个码点:

int index = s.offsetByCodePoints(0,i);
int cp = s.codePointAt(index);

:如果要遍历一个字符串,并依次查看每一个码点,可使用codePoints方法,它会生成一个int值的“流”,每一个int值对应一个码点。可以把它转换为一个数组,再完成遍历:

int[] codePoints = s.codePoints().toArray();

反之,要把一个码点数组转换为一个字符串,可以使用构造函数:

String str = new String(codePoints,0,codePoints.length);

7 String API

Java中的String类包含了50多个方法。

  • boolean startWith(String pre) 以 pre 开头
  • boolean endWith(String end) 以 end 结尾
  • int indexOf(String str) 返回与字符串str匹配的第一个子串的开始位置,如果不存在,返回-1
  • int indexOf(String str,int fromIndex) 从fromIndex开始计算,返回与字符串str匹配的第一个子串的开始位置,如果不存在,返回-1
  • int lastIndexOf(String str) 返回与字符串str匹配的最后一个子串的开始位置,这个位置从原始串尾开始计算;同样也可以有开始计算位置的参数fromIndex。
  • String replace(CharSequence oldstring,CharSequence newstring) 返回一个新的字符串。这个字符串用newstring代替原始字符串中的所有oldstring.可以用String或StringBuilder对象作为参数
  • String toLowerCase() 返回一个新的字符串(将原始字符串中的大写字母改为小写)
  • String toUpperCase() 返回一个新的字符串(将原始字符串中的小写字母改为大写)
  • String trim() 返回一个新的字符串。这个字符串删除了原始字符串头部和尾部的空格

在API注释中,有一些CharSequence类型的参数。这是一种接口类型,所有字符串都属于这个接口。CharSequence形参,完全可以传入String类型的实参。


8 构建字符串

有些时候,需要由较短的字符串构建字符串,而采用字符串连接的方式达到此目的的效率比较低。每次连接字符串,都会构建一个新的String对象,既耗时,又耗内存。

使用StringBuilder类可以避免这个问题的发生。

如果需要用许多小段的字符串构建字符串,那么应该按照下列步骤进行。

1.首先,构建一个空的字符串构建器:

StringBuilder builder = new StringBUilder();

2.当每次需要添加一部分内容时,就调用append方法:

builder.append(ch);  //ch表示一个字符
builder.append(str);  //str表示一个字符串

3.在需要构建字符串时调用toString方法,将可以得到一个String对象,其中包含了构建器中的字符序列:

String completedString = builder.toString();

:在JDK5.0引入StringBuilder类。这个类的前身是StringBuffer,其效率稍有些低,但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑,则应该使用StringBuilder替代它。

以下是StringBuilder类中的重要方法:

  • StringBuilder() 构建一个空的字符串构建器
  • int length() 返回构建器或缓冲器中的代码单元数量
  • StringBuilder append(String str) 追加一个字符串并返回this
  • StringBuilder append(Char c) 追加一个代码单元并返回this
  • void setCharAt(int i,Char c) 将第i个代码单元设置为c
  • StringBuilder insert(int offset,String str) 在offset位置插入一个字符串并返回this
  • StringBuilder insert(int offset,Char c) 在offset位置插入一个代码单元并返回this
  • StringBuilder delete(int startIndex,int endIndex) 删除偏移量从startIndex到endIndex-1的代码单元并返回this
  • String toString() 返回一个与构建器或缓冲器内容相同的字符串
### 回答1: 1 University students can understand innovation through learning from the past. 2. Students can better review by breaking down complex concepts into smaller components and studying the material in an organized way. 3. When learning from the past to understand innovation, it is important to focus on understanding the big picture and to not get bogged down in the details. ### 回答2: 1. 大学生如何理解温故而知新? 温故而知新是一种学习方法,它要求我们在学习新知识之前先回顾和巩固已经学过的知识。大学生理解温故而知新意味着要在学习新知识之前,先回顾和复习以前学过的相关知识或基础知识。通过温故,我们能够加深对已有知识的理解和记忆,从而更好地理解和掌握新的知识。 2. 学生如何更好地去复习? 学生要更好地复习,可以采取以下策略: 首先,制定一个合理的复习计划,将要复习的内容分配到不同的时间段,确保每个科目都有足够的时间。 其次,采用多种复习方法,如阅读教材、做练习题、参加讨论等,以帮助加深理解和牢固记忆。 另外,与同学或老师一起讨论复习内容,通过讲解和互动来加深理解。 此外,保持良好的学习习惯,比如及时复习、做好笔记等,能够帮助学生更好地掌握和复习知识。 3. 温故而知新的过程需要注意什么? 在温故而知新的过程中,需要注意以下几点: 首先,要有针对性,根据自己的学习需求和复习目标,选择性地回顾和复习相关知识点。 其次,要有系统性,将复习内容进行分类整理,形成一个清晰的知识框架,有助于加深理解和记忆。 另外,要关注重难点,重点复习那些相对较难或容易遗忘的知识点,加强对这些内容的学习和理解。 还要有耐心和恒心,温故而知新是一个持续的过程,需要长期坚持和不断巩固。 最后,要善于总结和归纳,通过整理和回顾复习过程中的笔记和练习,提炼出关键概念和思维模式,便于记忆和应用。 ### 回答3: 1. 大学生如何理解温故而知新? 大学生可以理解为通过回顾过去的知识和经验,来获取新的见解和理解。温故是指回顾已经学过的知识,了解其中的原理、概念和重要点。而知新则是指通过对新知识的学习,扩展和更新自己的知识体系。温故而知新相辅相成,是一个持续学习和发展的过程。 2. 学生如何更好地去复习? 学生可以通过以下方式更好地进行复习: - 制定合理的复习计划:根据时间安排和课程难度,合理分配复习时间,确保每个学科都有足够的复习时间。 - 多种复习方法结合:采用不同的学习方式,如阅读教材、做练习题、参与讨论、制作思维导图等,帮助巩固记忆和理解知识。 - 主动参与课堂:积极参与讨论和提问,与同学和老师交流,加深对知识的理解和记忆。 - 不断反思和总结:及时检查自己的复习情况,发现不足和问题,并及时调整学习方法和计划。 3. 温故而知新的过程需要注意什么? 在温故而知新的过程中,学生需要注意以下几点: - 有目的性地温故:针对具体的知识点或者问题进行回顾,明确自己的学习目标和重点。 - 理解和记忆结合:不仅要理解概念和原理,还要通过多次的复习和记忆,帮助信息在大脑中形成长期记忆。 - 理论联系实际:将学到的知识应用到实际情境中,加深对知识的理解和记忆。 - 及时巩固复习成果:通过做练习题、整理笔记、与同学讨论等方式,巩固复习的成果,确保知识掌握得更牢固。 - 长期持续学习:温故而知新是一个持续的过程,要保持学习的热情和动力,不断更新自己的知识体系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值