目 录
第1章 Java的API
第2章 Object类
2.1 Object类 概述
2.2 equals方法
2.3 to String 方法
第3章 String类
3.1 概述
3.2 String类创建方式和比较
3.3 String类的构造方法
3.4 String类的方法查找
3.5 String类方法查找练习
3.6 String类方法使用练习
第4章 字符串缓冲区
4.1 String Buffer类
4.2 String Buffer类的方法及练习
4.3 StringBuilder类
4.4 StringBuffer类案例拼接数组
4.5 对象的方法链调用
第5章 总结
第1章 Java的API
Java 的API(API: Application(应用) Programming(程序) Interface(接口))
Java API是JDK中提供给我们使用的类,这些类将底层的代码实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。
在JDK安装目录下有个src.zip文件,这个文件解压缩后里面的内容是所有Java类的源文件。可以在其中查看相对应的类的源码。我们在每次查看类中的方法时,都打开源代码进行查看的方式过于麻烦。可以通过查帮助文档的方式,来了解Java提供的API如何使用。如下图操作:查找Object类
第2章 Object类
2.1 Object类 概述
- Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。所有类在创建对象的时候,最终找的父类就是Object。
- Object类的构造方法是Object(),空参的构造方法,且第一行不是super,因为Object类没有父类,他已经是最顶层。
- 接口是否也继承Object类?接口的方法全部都是抽象的,没有构造方法,所以也就没有访问父类构造器的过程,所以接口没有继承父类的概念。
- 在Object类众多方法中,先学习equals方法与toString方法,其他方法后面课程中会陆续学到。
2.2 equals方法
1)equals方法比较内存地址
equals方法,用于比较两个对象是否相同,它其实就是使用两个对象的内存地址在比较。Object类中的equals方法内部使用的就是==比较运算符。
- 代码示例:
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name ,int age ) {
this.name= name;
this.age =age;
}
/*
* 将父类的equals方法重写
* 但是不改变父类方法的源代码,即原封不动的搬过来
* 方法equals比较的是内存地址,而每次new对象的地址也不同
*/
public boolean equals (Object obj) {
return this == obj ;
}
public void setName( String name) {
this.name = name;
}
public String getName() {
return name ;
}
public void setAge( int age) {
this.age = age;
}
public int getAge() {
return age ;
}
}
public class TestEquals {
public static void main(String[] args) {
//Person继承了Object类,同时继承了父类的方法equals
Person p1 = new Person("李四",24);
Person p2 = new Person("张三",23);
//Person对象p1,调用父类的方法equals,进行对象的比较
//p1.equals(p2);//输出结果为布尔类型,则用布尔类型变量接收,
boolean b = p1.equals(p2);
System.out.println(b); //输出结果为:false
}
}
图示:
返回值为true的情况:
public class TestEquals {
public static void main(String[] args) {
Person p1 = new Person("李四",24);
Person p2 = new Person("张三",23);
p1 = p2;//将p2的内存地址赋值给p1
boolean b = p1.equals(p2);
System.out.println(b); //输出结果为:true
}
}
2)equals方法比较对象属性
- 在开发中要比较两个对象是否相同,经常会根据对象中的属性值进行比较,也就是在开发经常需要子类重写equals方法根据对象的属性值进行比较。
==号和equals方法的区别
- ==是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型。用于基本数据类型比较的是值,用于引用数据类型比较的是地址
equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,如果没有重写Object类中的equals方法,equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性
代码示例:
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name ,int age ) {
this.name= name;
this.age =age;
}
/*
* 将父类的equals方法重写
* 实现比较对象中的年龄属性是否相同
*/
public boolean equals (Object obj) {
//相当于自己与自己比较,则不用走下列代码了
if( this == obj){
return true;
}
//对参数obj,非null判断
if( obj == null){
return false;
}
//判断参数obj接收的是Person对象,才能实现转型,否则也无意义
if (obj instanceof Person) {
// this.age == obj.age ;这样的写法是错误的,
//因为期间包括多态的向上转型,obj已经是父类类型,
//多态的弊端就是父类变量不能调用子类的变量
//为了调用成功进行比较,还需要向下转型,把obj转成Person类型
Person p = (Person)obj;
return this.age == p.age;
}
return false;
}
public void setName( String name) {
this.name = name;
}
public String getName() {
return name ;
}
public void setAge( int age) {
this.age = age;
}
public int getAge() {
return age ;
}
}
public class TestEquals {
public static void main(String[] args) {
Person p1 = new Person("李四",24);
Person p2 = new Person("张三",23);
//变成比较对象中的年龄属性是否相同
boolean b = p1.equals(p2);
System.out.println(b); //输出结果为:false
}
}
【注意】:在复写Object中的equals方法时,一定要注意public boolean equals(Object obj)的参数是Object类型,在调用对象的属性时,一定要进行类型转换,在转换之前必须进行类型判断。
图示:
3)避免本例中的Object类风险:
①参数Object还可以包含数组等。若不进行类型判断,Person类与数组比较也好,与Dog类比较年龄也好,都无意义。
② Object类还包括null,也就是所有数据类型传参时都可以传null,此时就不用比了。
③Object类中包含要进行比较的对象,如果传参也是该对象,相当于自己与自己比较,则不用走下面的代码了。
2.3 toString 方法
1)概述
- toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写。
2) 重写toString方法
代码示例:
定义类:
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name ,int age ) {
this.name= name;
this.age =age;
}
/*
* 重写父类的方法toString()
* 没有必要让调用者看到内存地址
* 要求: 方法中,返回类中所有成员变量的值
*/
public String toString(){
return name + age;
}
/*
* 将父类的equals方法重写
*/
public boolean equals (Object obj) {
if( this == obj){
return true;
}
if( obj == null){
return false;
}
if (obj instanceof Person) {
Person p = (Person)obj;
return this.age == p.age;
}
return false;
}
public void setName( String name) {
this.name = name;
}
public String getName() {
return name ;
}
public void setAge( int age) {
this.age = age;
}
public int getAge() {
return age ;
}
}
测试类:
public class TesttoString {
public static void main(String[] args) {
//调用Person类的方法toString()
//输出语句中,写的是一个对象,默认调用对象的toString方法,也就是内存地址
//但是改写之后,输出的就是改写的内容
Person p1 = new Person("李四",24);
Person p2 = new Person("张三",23);
System.out.println(p1);//输出结果为:李四24
System.out.println(p2); //输出结果为:张三23
}
}
第3章 String类
3.1 概述
1)概念
- 查阅API中的String类的描述,发现String 类代表字符串。Java 程序中的所有字符串字(如 “abc” )都作为此类的对象。
2)不变性
字符串是常量,在创建之后不能更改,其实就是说一旦这个字符串确定了,那么就会在内存区域中就生成了这个字符串。字符串本身不能改变,但str变量中记录的地址值是可以改变的。
源码分析,String类底层采用的是字符数组:
private final char value[]
private 修饰说明value只能在String类内部使用,而且又没有提供get方法,所以外部无法获取value数组,就无法改变数组中元素的值
final修饰说明value是常量,一旦创建,就不能被改变,value一旦被初始化成某个数组,将永远指向这个数组,不可能再指向其它的数组了
3)举例:
① 代码示例:
② 图解:
3.2 String类 创建方式和比较
1)两种创建方式
- ① String s3 = “abc”;
* 在内存中只有一个对象。这个对象在字符串常量池中 - ② String s4 = new String(“abc”);
* 在内存中有两个对象。一个new的对象在堆中,一个字符串本身对象,在字符串常量池中
2)比较两种创建方式
1)代码示例:
public class StringDemo2 {
public static void main(String[] args) {
//字符串定义方式2个, 直接= 使用String类的构造方法
String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1);//输出:abc
System.out.println(str2);//输出:abc
System.out.println(str1==str2);//引用数据类型,比较对象的地址 false
System.out.println(str1.equals(str2));//true
}
}
2)分析
3.3 String类 的构造方法
1)常见构造方法
public String(byte[] bytes):把字节数组转成字符串
public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串
常见构造方法public String(char[] value):把字符数组转成字符串
- public String(char[] value,int index,int count):把字符数组的一部分转成字符串
2)案例代码
① public String(byte[] bytes):把字节数组的全部转成字符串
/*
* String的构造方式,重载形式
*/
public class StringDemo1 {
public static void main(String[] args) {
function();
}
/*
* 定义方法,String类的构造方法
* String(byte[] bytes) 传递字节组
* 通过使用平台的默认字符集解码指定的byte数组,构造一个新的String
* 平台:机器操作系统
* 默认字符集:操作系统中的默认编码表,默认编码表CBK
*/
public static void function() {
byte [] bytes = {97,98,99,100};
//调用String类的构造方法,传递字节数组
String s = new String(bytes);
System.out.println(s); //输出结果为:abcd
//从结果可见,将字节数组的每个字节,查询了编码表得到的结果
//如果为负数字节,则查询GBK输出汉字,一个汉字采用2个字节表示
byte [] bytes1 = {-97,-98,-99,-100};
String s1 = new String(bytes1);
System.out.println(s1);//输出结果为:煘潨
}
}
② public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串
/*
* String的构造方式,重载形式
*/
public class StringDemo2{
public static void main(String[] args) {
function();
}
/*
*
* String(byte[] bytes, int offset, int length) 传递字节数组一部分
* bytes 要解码为字符的byte
* offset 要解码的第一个byte的索引
* length 要解码的byte个数,填数字几就转几个, 不是结束的索引
*/
public static void function() {
byte[] bytes2 ={65,66,67,68,69};
//调用String构造方法,传递数组,传递2个int值
String s2 = new String(bytes2,1,3);
System.out.println(s2);//输出结果为:BCD
}
}
③ public String(char[] value):把字符数组的全部转成字符串
/*
* String类构造方法
* String类的构造方法,重载形式
*
*/
public class StringDemo3 {
public static void main(String[] args) {
function_1();
}
/*
* String(char[] value) 传递字符数组
* 将字符数组,转成字符串, 字符数组的参数不查询编码表
*/
public static void function_1(){
char[] ch = {'a','b','c','d','e','f'};
//调用String构造方法,传递字符数组
String s1 = new String(ch);
System.out.println(s1);//输出结果为:abcdef
}
}
④ public String(char[] value,int index,int count):把字符数组的一部分转成字符串
/*
* String类构造方法
* String类的构造方法,重载形式
*
*/
public class StringDemo4 {
public static void main(String[] args) {
function_1();
}
/*
* String(char[] value, int offset, int count) 传递字符数组
* 将字符数组的一部分转成字符串
* offset 数组开始索引
* count 个数
*/
public static void function_1(){
char[] ch = {'a','b','c','d','e','f'};
//调用String构造方法,传递字符数组
String s2 = new String(ch,1,4);
System.out.println(s2);//输出结果为:bcde
}
}
3.4 String类 的方法查找
- String类中有很多的常用的方法,我们在学习一个类的时候,不要盲目的把所有的方法尝试去使用一遍,这时我们应该根据这个对象的特点分析这个对象应该具备那些功能,这样大家应用起来更方便。
字符串是一个对象,那么它的方法必然是围绕操作这个对象的数据而定义的。我们想想字符串中有哪些功能呢?
1)方法介绍
- int length(): 返回字符串的长度
- String substring(int beginIndex,int endIndex): 获取字符串的一部分
- String substring(int beginIndex): 获取字符串的一部分
- boolean startsWith(String prefix): 判断一个字符串是不是另一个字符串的前缀,开头
- boolean endsWith(String prefix): 判断一个字符串是不是另一个字符串的后缀,结尾
- boolean contains (String s): 判断一个字符串中,是否包含另一个字符串
- int indexOf(char ch): 查找一个字符,在字符串中第一次出现的索引,被查找的字符不存在,返回-1
- byte[] getBytes(): 将字符串转成字节数组,此功能和String构造方法相反,byte数组相关的功能,查询编码表
- char[] toCharArray(): 将字符串转成字符数组,功能和构造方法相反
- boolean equals(Object obj): 方法传递字符串,判断字符串中的字符是否完全相同,如果完全相同返回true
- boolean equalsIgnoreCase(String s): 传递字符串,判断字符串中的字符是否相同,忽略大小写
2)案例代码
public class StringDemo4 {
public static void main(String[] args) {
function_9();
}
/*
* boolean equals(Object obj)
* 方法传递字符串,判断字符串中的字符是否完全相同,如果完全相同返回true
*
* boolean equalsIgnoreCase(String s)
* 传递字符串,判断字符串中的字符是否相同,忽略大小写
*/
public static void function_9(){
String str1 = "Abc";
String str2 = "abc";
//分别调用equals和equalsIgnoreCase
boolean b1 = str1.equals(str2);
boolean b2 = str1.equalsIgnoreCase(str2);
System.out.println(b1);//输出结果为:false
System.out.println(b2);//输出结果为:true
}
/*
* char[] toCharArray() 将字符串转成字符数组
* 功能和构造方法相反
*/
public static void function_8(){
String str = "itcast";
//调用String类的方法toCharArray()
char[] ch = str.toCharArray();
for(int i = 0 ; i < ch.length ; i++){
System.out.println(ch[i]);//转成单个字符
}
}
/*
* byte[] getBytes() 将字符串转成字节数组
* 此功能和String构造方法相反
* byte数组相关的功能,都会查询编码表
*/
public static void function_7(){
String str = "abc";//若str= “汉字”,结果为:-70,-70,-41,-42
//调用String类方法getBytes字符串转成字节数组
byte[] bytes = str.getBytes();
for(int i = 0 ; i < bytes.length ; i++){
System.out.println(bytes[i]);//输出结果为97,98,99
}
}
/*
* int indexOf(char ch)
* 查找一个字符,在字符串中第一次出现的索引
* 被查找的字符不存在,返回-1
*/
public static void function_6(){
String str = "itcast.cn";
//调用String类的方法indexOf
int index = str.indexOf('x');//若为‘t’输出结果为1
System.out.println(index);//输出结果为-1,意为没有
}
/*
* boolean contains (String s)
* 判断一个字符串中,是否包含另一个字符串
*/
public static void function_5(){
String str = "itcast.cn";
//调用String类的方法contains
boolean b =str.contains("ac");//若改成“ca”输出结果为true
System.out.println(b);//输出结果为false
}
/*
* boolean endsWith(String prefix)
* 判断一个字符串是不是另一个字符串的后缀,结尾
* Demo.java
* .java输出结果为true,jaqa输出结果为false,
*/
public static void function_4(){
String str = "Demo.java";
//调用String类方法endsWith
boolean b = str.endsWith(".java");
System.out.println(b); //输出结果为true
}
/*
* boolean startsWith(String prefix)
* 判断一个字符串是不是另一个字符串的前缀,开头
* howareyou
* 若how返回值为true,ow为false,hOw为false
*/
public static void function_3(){
String str = "howareyou";
//调用String类的方法startsWith
boolean b = str.startsWith("how");//输出结果为:为true
System.out.println(b);
}
/*
* String substring(int beginIndex,int endIndex) 获取字符串的一部分
* 返回新的字符串
* beginIndex:包含头,endIndex:不包含尾巴
*
* String substring(int beginIndex)获取字符串的一部分
* 包含头,后面的字符全要
*/
public static void function_2(){
String str = "howareyou";
//调用String类方法substring获取字符串一部分
str.substring(1, 5);//输出结果为:howareyou,因为字符串是常量,一旦赋值不可改变
//也可以用原来的变量接收新的字符串
str= str.substring(1, 5);//若(1,12)则会报错,没有那么多字符;(1,1)包含头不包含尾,造成混乱,则什么都不输出
System.out.println(str);//输出结果为:owar
String str2 = "HelloWorld";
str2 = str2.substring(1);
System.out.println(str2);
}
/*
* int length() 返回字符串的长度
* 包含多少个字符
*/
public static void function(){
String str = "cfxdf#$REFewfrt54GT";
//调用String类方法length,获取字符串长度
int length = str.length();
System.out.println(length);
}
}
3.5 String类方法查找练习
- 下面的需求所对应的方法,要求大家自己动手在API中查找,并进行方法使用。
- 判断该字符串的内容是否为空的字符串
- 获取给定的字符,在该字符串中第一次出现的位置
- 获取该字符串中指定位置上的字符
- 把该字符串转换成 小写字符串
- 把该字符串转换成 大写字符串
- 在该字符串中,将给定的旧字符,用新字符替换
- 在该字符串中, 将给定的旧字符串,用新字符串替换
- 去除字符串两端空格,中间的不会去除,返回一个新字符串
3.6 String类方法使用练习
1)获取指定字符串中,大写字母、小写字母、数字的个数
①题目分析
- 为了统计大写字母、小写字母、数字的个数。创建3个计数的变量。
- 为了获取到字符串中的每个字符,进行字符串的遍历,得到每个字符。
- 对得到的字符进行判断,如果该字符为大写字母,则大写字母个数+1;如果该字符为小写字母,则小写字母个数+1;如果该字符为数字,则数字个数+1。
- 显示大写字母、小写字母、数字的个数
② 案例代码
/*
* 获取指定字符串中,大写字母、小写字母、数字的个数。
*思想:
* 1. 计数器,就是int变量,满足一个条件 ++
* 2. 遍历字符串, 长度方法length() + charAt() 遍历
* 3. 字符判断是大写,是小写,还是数字
*
*/
public class StringTest {
public static void main(String[] args) {
getCount("&A%Ve458ty1");
}
public static void getCount (String str) {
//定义三个变量,计数
int upper = 0 ;//大写
int lower = 0 ;//小写
int digit = 0 ;//数字
//对字符串遍历
for(int i = 0;i<str.length();i++) {
//运用String类方法charAt,根据索引获取字符
char c = str.charAt(i);
//利用编码表做判断大小写:
// 65-90:大写字母 97-122:小写字母 48-57:数字
//这里写97或者'A'的效果是一样的,自动转换
if(c >='A' && c <='Z'){
upper++;
}else if( c >= 97 && c <= 122){
lower++;
}else if( c >= 48 && c <='9'){
digit++;
}
}
System.out.println(upper);//输出结果为:2
System.out.println(lower);//输出结果为:3
System.out.println(digit);//输出结果为:4
}
}
2)将字符串中,第一个字母转换成大写,其他字母转换成小写,并打印改变后的字符串。
① 题目分析
- 把字符串分为两个部分,第一部分为字符串中第一个字母,第二部分为剩下的字符串。
- 把第一部分字符串转换成大写字母,把第二部分字符串转换成小写字母
- 把两部分字符串连接在一起,得到一个完整的字符串
② 案例代码
/*
* 将字符串中,首字母转换成大写,其他字母转换成小写,并打印改变后的字符串。
* 思想:
* 获取首字母, charAt(0):返回char类型 substring(0,1):包含头不包含尾,返回String类型
* 转成大写 toUpperCase()
* 获取剩余字符串, substring(1) toLowerCase()
*/
public class StringTest1 {
public static void main(String[] args) {
System.out.println(toConvert ("aBsfVfG"));//输出结果:Absfvfg
}
public static String toConvert (String str) {
//定义变量保存首字母和其余字符
String first = str.substring(0,1);
String after = str.substring(1);
//调用String类方法,进行大小写转换
first = first.toUpperCase();//注意此处first.toUpperCase()原字符不变,必须重新接收一下
after = after.toLowerCase();//注意此处after.toLowerCase()原字符不变,必须重新接
return first+after;
}
}
3)查询大字符串中,出现指定小字符串的次数
① 题目分析
- 在大串中,查找小串出现的位置,出现了就次数+1
- 在上次小串出现位置的后面继续查找,需要更改大串的内容为上次未查询到的字符串。
- 回到第一步,继续查找小串出现的位置,直到大串中查询不到小串为止
② 案例代码
/*获取一个字符串中,另一个字符串出现的次数
* 思想:
* 1. indexOf到字符串中到第一次出现的索引
* 2. 找到的索引+被找字符串长度,截取字符串
* 3. 计数器++
*/
public class StringTest2 {
public static void main(String[] args) {
System.out.println(getStringCount("hellojava,nijavahaojava,javazhenbang", "java"));
//输出结果:4
}
public static int getStringCount(String str,String key) {
//定义计数器
int count = 0 ;
//定义变量,保存indexOf查找后的索引结果
int index = 0;
//开始循环找,条件结束indexOf==-1,则结束
while ((index = str.indexOf(key))!=-1){
count++;
//获取到的索引,和字符串长度求和,截取字符串
str = str.substring(index+key.length());
}
return count;
}
}
第4章 字符串缓冲区
4.1 String Buffer类
1)StringBuffer类概述
- 通过JDK提供的API,查看StringBuffer类的说明
- 线程安全的可变字符序列
- 底层采用字符数组实现,初始容量为16
2)StringBuffer和String的区别
- String是一个不可变的字符序列
- StringBuffer是一个可变的字符序列
4.2 String Buffer类的方法及练习
1)方法介绍
- StringBuffer append(), 将任意类型的数据,添加缓冲区
- append 返回值,写return this
- 调用者是谁,返回值就是谁
- delete(int start,int end): 删除缓冲区中字符
- 开始索引包含,结尾索引不包含
- insert(int index, 任意类型): 将任意类型数据,插入到缓冲区的指定索引上
- replace(int start,int end, String str): 将指定的索引范围内的所有字符,替换成新的字符串
- reverse(): 将缓冲区中的字符反转
- String toString(): 继承Object,重写toString()
- 将缓冲区中的所有字符,变成字符串
2)案例代码
public class StringBufferDemo {
public static void main(String[] args) {
function_5();
}
/*
* StringBuffer类的方法
* String toString() 继承Object,重写toString()
* 将缓冲区中的所有字符,变成字符串
*/
public static void function_5(){
StringBuffer buffer = new StringBuffer();
buffer.append("abcdef");
buffer.append(12345);
//将可变的字符串缓冲区对象,变成了不可变String对象
String s = buffer.toString();
System.out.println(s);//输出结果为:abcdef12345,原来是缓冲区的字符,现在变为不可变的String对象
}
/*
* StringBuffer类的方法
* reverse() 将缓冲区中的字符反转
*/
public static void function_4(){
StringBuffer buffer = new StringBuffer();
buffer.append("abcdef");
buffer.reverse();
System.out.println(buffer);//输出结果为:fedcba
}
/*
* StringBuffer类方法
* replace(int start,int end, String str)
* 将指定的索引范围内的所有字符,替换成新的字符串
* 也是前包含,后不包含
*/
public static void function_3(){
StringBuffer buffer = new StringBuffer();
buffer.append("abcdef");
buffer.replace(1, 4, "Q");
System.out.println(buffer);//输出结果为:aQef
}
/*
* StringBuffer类方法 insert
* insert(int index, 任意类型)
* 将任意类型数据,插入到缓冲区的指定索引上
*/
public static void function_2(){
StringBuffer buffer = new StringBuffer();
buffer.append("abcdef");
buffer.insert(3, 9.5);
System.out.println(buffer);//输出结果为:abc9.5def
//若 buffer.insert(6, 9.5);则9.5出现在索引6的位置上,即最后
//若 buffer.insert(7, 9.5);则会报错,越界异常,因为索引6上还什么都没有
}
/*
* StringBuffer类方法
* delete(int start,int end) 删除缓冲区中字符
* 开始索引包含,结尾索引不包含
*/
public static void function_1(){
StringBuffer buffer = new StringBuffer();
buffer.append("abcdef");
buffer.delete(1,5);
System.out.println(buffer);//输出结果为:af
//想要全部删除时:buffer.delete(0,buffer.length());
}
/*
* StringBuffer类方法
* StringBuffer append, 将任意类型的数据,添加缓冲区
* append 返回值,写return this
* 调用者是谁,返回值就是谁
*/
public static void function(){
StringBuffer buffer = new StringBuffer();
//调用StringBuffer方法append向缓冲区追加内容
//本身返回值就是buffer类型,所以可以一直调用,即方法调用链
buffer.append(6).append(false).append('a').append(1.5);
System.out.println(buffer);//输出结果为:6falsea1.5
}
}
4.3 StringBuilder类
1)StringBuilder的概述
- 查阅API发现还有一个StringBuilder类,它也是字符串缓冲区。
- 也是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
- 目前,我们还没有涉及到线程与同步,知道结论StringBuilder比StringBuffer快即可。为什么快,我们会在学习线程时讲解。
2)要点
StringBuffer和StringBuilder的区别
- StringBuffer是jdk1.0版本的,是线程安全的,效率低
- StringBuilder是jdk1.5版本的,是线程不安全的,效率高
String和StringBuffer,StringBuilder的区别
- String是一个不可变的字符序列
- StringBuffer,StringBuilder是可变的字符序列
4.4 StringBuffer类案例拼接数组
1)题目分析
- 定义StringBuffer对象
- 遍历数组,按照格式要求拼接处新的字符串,追加到StringBuffer容器中
- 将StringBuffer中的内容以String的形式返回
2)代码示例:
/*
* int[] arr = {34,12,89,68};将一个int[]中元素转成字符串
* 格式 [34,12,89,68]
* 原来的做法: String s = "["
* 数组遍历
* s+= arr[i];
* s+"]"
* 现在用StringBuffer实现,节约内存空间, String + 在缓冲区中,append方法
*/
public class StringBufferTest {
public static void main(String[] args) {
int[] arr = {4,1,4,56,7,8,76};
System.out.println(toString(arr));
}
public static String toString(int[] arr){
//创建字符串缓冲区
StringBuffer buffer = new StringBuffer();
buffer.append("[");
//数组遍历
for(int i = 0 ; i < arr.length;i++){
//判断是不是数组的最后一个元素
if(i == arr.length-1){
buffer.append(arr[i]).append("]");
}else{
buffer.append(arr[i]).append(",");
}
}
return buffer.toString();//是缓冲区内容变成字符串
}
}
4.5 对象的方法链调用
- 在 4.2 String Buffer类的方法及练习的代码示例中涉及过,开发中,会遇到调用一个方法后,返回一个对象的情况。然后使用返回的对象继续调用方法。
- 这种时候,我们就可以把代码现在一起,如append方法一样,代码如下:
创建一个字符串缓冲区对象。用于存储数据。
StringBuffer sb = new StringBuffer();
添加数据。不断的添加数据后,要对缓冲区的最后的数据进行操作,必须转成字符串才可以。
String str = sb.append(true).append(“hehe”).toString();
- 这种时候,我们就可以把代码现在一起,如append方法一样,代码如下:
/*
* StringBuffer类方法
* StringBuffer append, 将任意类型的数据,添加缓冲区
* append 返回值,写return this
* 调用者是谁,返回值就是谁
*/
public static void function(){
StringBuffer buffer = new StringBuffer();
//调用StringBuffer方法append向缓冲区追加内容
//本身返回值就是buffer类型,所以可以一直调用,即方法调用链
buffer.append(6).append(false).append('a').append(1.5);
System.out.println(buffer);//输出结果为:6falsea1.5
}
第5章 总结
5.1 API
- api的概述: 就是java替我们写好的一些类,他封装了一些功能,我们仅仅只需要知道如何使用即可
5.2 Object
- object的概述:
A、 object是所有的类父类
B、 object中的所有方法,子类都能使用(接口不是object的子类)
5.3 Object 类中常用方法
1)equals() :
底层调用其实就是== 方法
== 方法:
基本数据类: 比较的是内容(值)
引用数据类型:比较的是内存地址值- String 的equals比较的是内容
2)String toString():
问题:为什么要重写toString()方法
- 答:打印时默认会调用toString()方法 ,打印就是内存地址值,很多时候,我们不需要内存地址值,想看到的是子类的特有属性值,这时就需要重写toString()方法
5.4 String
- 在String 中认为都是对象,String str = “…”;
所以str 是对象,”“也是对象 String 是一个常量,其本质就是private final 修饰的字符数组
String的构造方法:
new String(byte [] bytes, int offset,int length);
offset: 数据解锁起始位置
length:需要解锁的位数substring(int start ,int end ); 包含头,不包含尾。 截取一段字符
substring(int start); 从某一位到尾
startsWith(String str) 判断以什么开头
endsWith(String str) 判断以什么结尾
contains(String str) 判断是否包含
indexOf(String str)
charAt(int index)
equals() 注意:要区分大小写
equalsIgnoreCase 不区分大小写
getBytes()
toCharArray()
5.5 StringBuilder && StringBuffer
StringBuilder 是字符串缓冲对象,底层是一个没有用final修饰的数组,并且长度默认为16,底层是一个”可变数组”
注意:是底层自动帮我们创建新数组,数组一旦创建,是不可变的
5.6 方法总结
1)Object: 它是所有类的超类,祖宗类。java中所有的类都直接或间接的继承这个类
- 方法
- public String toString() 返回当前对象中的内容, 对于Object类默认操作来说,返回的对象的类型+@+内存地址值
- public boolean equals(Object obj) 比较两个对象内容是否相同,对于Object类默认操作来说,比较的是地址值
- 在开发中要比较两个对象属性值是否相同,需要子类重写equals方法根据对象的属性值进行比较。
2)String: 字符串类,字符串是常量;它们的值在创建之后不能更改
方法
- boolean equals(Object obj) 判断两个字符串中的内容是否完全相同
- boolean equalsIgnoreCase(String str) 判断两个字符串中的内容是否相同, 忽略大小写
- boolean contains(String str) 判断该字符串中 是否包含给定的字符串
- boolean startsWith(String str) 判断该字符串 是否以给定的字符串开头
- boolean endsWith(String str) 判断该字符串 是否以给定的字符串结尾
- boolean isEmpty() 判断该字符串的内容是否为空的字符串 “”
- int length() 获取该字符串的长度
- char charAt(int index) 获取该字符串中指定位置上的字符
- String substring(int start) 从指定位置开始,到末尾结束,截取该字符串,返回新字符串
- String substring(int start,int end) 从指定位置开始,到指定位置结束,截取该字符串,返回新字符串
- int indexOf(int ch ) 获取给定的字符,在该字符串中第一次出现的位置
- int indexOf(String str) 获取给定的字符串,在该字符串中第一次出现的位置
- int indexOf(int ch,int fromIndex) 从指定位置开始,获取给定的字符,在该字符串中第一次出现的位置
- byte[] getBytes() 把该字符串 转换成 字节数组
- char[] toCharArray() 把该字符串 转换成 字符数组
- String replace(char old,char new) 在该字符串中,将给定的旧字符,用新字符替换
- String replace(String old,String new) 在该字符串中, 将给定的旧字符串,用新字符串替换
- String trim() 去除字符串两端空格,中间的不会去除,返回一个新字符串
- String toLowerCase() 把该字符串转换成 小写字符串
- String toUpperCase() 把该字符串转换成 大写字符串
- int indexOf(String str,int fromIndex) 从指定位置开始,获取给定的字符串,在该字符串中第一次出现的位置
2)StringBuffer/StringBuilder:
- 方法
- public StringBuffer append(String str) 在原有字符串缓冲区内容基础上,在末尾追加新数据
- public StringBuffer insert(int offset,String str) 在原有字符串缓冲区内容基础上,在指定位置插入新数据
- public StringBuffer deleteCharAt(int index) 在原有字符串缓冲区内容基础上,删除指定位置上的字符
- public StringBuffer delete(int start,int end) 在原有字符串缓冲区内容基础上,删除指定范围内的多个字符
- public StringBuffer replace(int start,int end,String str)在原有字符串缓冲区内容基础上,将指定范围内的多个字符 用给定的字符串替换
- public StringBuffer reverse() 将字符串缓冲区的内容 反转 “abc”—-“cba”
- public String substring(int start) 从指定位置开始,到末尾结束,截取该字符串缓冲区,返回新字符串
- public String substring(int start,int end) 从指定位置开始,到指定位置结束,截取该字符串缓冲区,返回新字符串