【Java学习笔记四】——String类
声明:本文章内容主要摘选自尚硅谷宋红康Java教程、《Java核心卷一》、《Java语言程序设计-基础篇》、廖雪峰Java教程,示例代码部分出自本人,更多详细内容推荐直接观看以上教程及书籍,若有错误之处请指出,欢迎交流。
一、字符串类String
1.概念
字符串(string)是由字符构成的一个序列。在很多语言中,字符串都被当做字符数组来处理,但是在Java中,字符串是一个对象。String类中有11个构造方法以及40多个处理字符串的方法。这不仅在程序设计中非常有用,而且也是一个学习类和对象的很好的例子。一个字符串对象可以由字符串字面量或字符数组创建,如:
String s1 = "king";//字面量定义
String s2 = new String("apple");
char[] charArray = {'n','i','c','e'};
String s3 = new String(charArray);//字符数组定义
2.String的不可变性
String对象是不可变的,它的内容是不能改变的。(String类加了final关键字)
体现:
①当对字符重新赋值时,需要重写指定内存区域赋值,不能使用原有value进行赋值;
②当对现有的字符进行连接操作时,也需要重新指定内存区域赋值,不能使用原有value进行赋值;
③当String字面量相同时,会替换为同一个String对象的引用,常量连接的结果也被优化为一个字符串。
String s1 = "Hello";
String s2 = "World";
String s3 = "HelloWorld";
String s4 = s1 + "World";
String s5 = s1 + s2;
String s6 = "Hello" + "World";
System.out.println(s3 == s4);//false
System.out.println(s3 == s5);//false
System.out.println(s4 == s5);//false
System.out.println(s3 == s6);//true
System.out.println(s4 == s6);//false
//常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
//只要其中有一个是变量,结果就在堆中
//可以简单认为若加上任何一个变量则无法相等,字面量之间相加则会相等(此处的==是指地址相等,不是内容)
关于这一特点需要了解一下String在内存中的存储特点,这里我简单介绍一下,如果想要了解更多细节可以看视频或者学习Java虚拟机。
创建一个String对象时,其引用存储在栈空间中,而字符串有2种存储方式:
方式一:通过字面量定义的方式:此时的字符串声明在方法区中的字符常量池中。
方式二:通过new+构造器的方式:此时的字符串保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
3.字符串的转换
String 与char[]的互相转化
- String-->char[]:调用String类的toCharArray()
- char[]-->String:调用String类的构造器
String 与 基本数据类型的互相转化
PS:此处涉及包装类的内容,可以先记住就行,不必强行理解,字符串的转换在做项目时还是很实用的,一定要掌握
- int--> String :调用String类的valueOf(int num)
- char--> String :调用String类的valueOf(char c)
- boolean--> String :调用String类的valueOf(boolean value)
- …………
- String-->int:调用Integer类的parseInteger(String str)
- String-->char:调用String类的charAt(int index)
- String-->boolean:调用Boolean类的parseBoolean(String str)
- …………
public class String3 {
public static void main(String[] args) {
//String --> char[]
String s1 = "AMDYES!";
char[] ch1 = s1.toCharArray();
for (int i = 0; i < ch1.length; i++) {
System.out.print(ch1[i]);
if(i == 2) System.out.print(" ");
}
//基本数据类型 --> String
int num1 = 666;
char c1 = 'A';
boolean b = false;
String s2 = String.valueOf(num1);
String s3 = String.valueOf(c1);
String s4 = String.valueOf(b);
System.out.println("\n" + num1 + " " + c1 + " " + b);
//String --> 基本数据类型
String s5 = "888";
String s6 = "E";
String s7 = "32.13";
int num2 = Integer.parseInt(s5);
char c2 = s6.charAt(0);
double num3 = Double.parseDouble(s7);
System.out.println(num2 + " " + c2 + " " + num3);
}
}
关于String的这些属性,下面给出2个面试题,答案放在文末。
面试题一:String s=new String("abc");方式创建对象,在内存中创建了几个对象?
//面试题二:请问输出结果是什么?
public class String2 {
String str = new String("good");
char[] ch = {'t', 'e', 's', 't'};
public void change(String str, char[] ch){
str = "test ok";
ch[0] = 'b';
}
public static void main(String[] args) {
String2 ex = new String2();
ex.change(ex.str, ex.ch);
System.out.println(ex.str);
System.out.println(ex.ch);
}
}
二、String常用类
1.字符串的比较
- boolean isEmpty():判断是否是空字符
- boolean equals(Object obj):比较字符的内容是否相同
- boolean equalsIgnoreCase(String anotherstring):与equals方法类似,忽略大小写
- int compareTo(String anotherstring):比较两个字符串的大小
注意:运算符"=="只能检测string1和string2是否指向同一个对象,但它不会告诉你它们的内容是否相同。因此,不能使用"=="运算符判断两个字符串变量的内容是否相同。
2.字符串的长度、字符以及字符串的组合
- int length():返回字符串的长度
- char charAt(int index):返回某索引处的字符
- String concat(String str):将指定字符串连接到此字符串的结尾。等价于用"+"
3.获取子串
- String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
- String substring(int beginIndex,int endIndex):返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
4.字符串转换、替换与分隔
- String toLowercase():使用默认语言环境,将 String 中的所有字符转换为小写
- String toUppercase():使用默认语言环境,将 String 中的所有字符转换为大写
- String trim():返回去掉两端的空白字符之后的新字符串
- String replace(char oldChar,char newchar):返回用一个新字符替换这个字符串中所有和它匹配的字符的新字符串
- newChar String replace(Charsequence target,Charsequence replacement):使用指定的字面值替换序
- String replaceALL(String regex,String replacement):使用给定的 replacement 替换此字符串
- String replaceFirst(String regex,String replacement):使用给定的 replacement 替换此字符串
5.依照模式进行匹配
- boolean matches(String regex):告知此字符是否匹配给定的正则表达式。
- String[]split(String regex):根据给定正则表达式的匹配拆分此字符串。
- String[]split(String regex,int limit):根据匹配给定的正则表达式来拆分此字符,最多不超过limit
6.子串
- boolean endsWith(String suffix):测试此字符是否以指定的后缀结束
- boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
- boolean startsWith(String prefix,int toffset):测试此字符a从指定索引开始的子字符串是否以指定的前缀开始
- boolean contains(CharSequence s):当且仅当此字符包含指定的 char 值序列时,返回 true
- int indexof(String str):返回指定子字符在此字符有中第一次出现处的索引
- int indexof(String str,int fromIndex):返回指定子字符在此字符有中第一次出现处的索引,从指定的索引开始
- int lastIndexof(String str):返回指定子字符转在此字符串中最右边出现处的索引
- int lastIndexof(String str,int fromIndex):返回指定子字符在此字符有中最后一次出现处的索引,从指定的索引开始反向
注:indexof和LastIndexof方法如果未找到都是返回-1
三、StringBuffer与StringBuilder
1.概念
StringBuilder/StringBuffer类是可以替代String类的另一种处理字符串的解决方案。一般来说,只要使用字符串的地方,都可以使用stringBuilder/stringBuffer类。只不过StringBuffer是Java早期的一个StringBuilder的线程安全版本,它通过同步来保证多个线程操作StringBuffer也是安全的,但是同步会带来执行速度的下降。StringBuilder和StringBuffer接口完全相同,现在完全没有必要使用StringBuffer。
那么为什么需要StringBuilder类呢,它其实是为了弥补String的不足——在拼接字符串String时,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象。
2.常用类
- StringBuilder append(xxx):提供了很多的append()方法,用于进行字符串拼接
- StringBuilder delete(int start,int end):删除指定位置的内容
- StringBuilder replace(int start,int end,String str):把[start,end)位置替换为str
- StringBuilder insert(int offset,xxx):在指定位置插入xxx
- StringBuilder reverse():把当前字符序列逆转
- publLic int indexOf(String str)
- public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
- public int length()
- public char charAt(int n)
- public void setCharAt(int n,char ch)
public class StringBuilderTest {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(20);
for (int i = 0; i < 10; i++) {
sb.append(i);
sb.append(',');
}
String s = sb.toString();
System.out.println(sb);
System.out.println(s);
}
}
面试题一答案:两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。只要其中有一个是变量,结果就在堆中如果拼接的结果调用intern()方法,返回值就在常量池中。
面试题二答案:good best(String不可变,char[]作为引用数据类型可变)
此笔记仅针对有一定编程基础的同学,且本人只记录比较重要的知识点,若想要入门Java可以先行观看相关教程或书籍后再阅读此笔记。
最后附一下相关链接:
Java在线API中文手册
Java platform se8下载
尚硅谷Java教学视频
《Java核心卷一》