一、API概述
什么是API
- API(Application Programming interface):应用程序编程接口。
- 简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了。
二、Object类
Object是Java中的顶级父类
所有的类都直接或间接的继承于Object类
- 在继承里面,子类里面的共性才会往父类里面抽取,在Java当中没有一个属性是所有类的共性,所以说Object类当中是没有成员变量的,既然没有成员变量,那么就没有有参的构造方法。
- 对于任何一个类的构造方法,在第一行,它都有一个隐藏的super( ),是默认访问父类的无参构造。
提出问题:那为什么是访问无参构造而不是访问有参构造呢?
- 因为在顶级父类Object当中,它只有无参的构造方法。
1. Object类:toString方法
Object的toString方法的基本作用是什么,存在的意义是什么?
- 基本作用:给子类继承,子类对象调用可以返回自己的地址。
- 意义:让子类重写,以便返回子类对象的内容。
package com.gch.d9_api_object;
import java.util.Objects;
public class Student { // extends Object{
private String name;
private char sex;
private int age;
/**
重写toString方法,返回对象的内容信息
*/
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
'}';
}
public Student() {
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.gch.d9_api_object;
/**
目标:掌握Object类中toString方法的使用
默认返回当前对象在堆内存当中的地址,并且是十六进制的地址
*/
public class Test1 {
public static void main(String[] args) {
Student s = new Student("小明",'男',23);
// String rs = s.toString();
// System.out.println(rs);
System.out.println(s.toString());
// 直接输出对象变量,默认可以省略toString调用不写的
System.out.println(s);
}
}
2、Object类:equals方法
- Object的equals方法的基本作用:默认是与另一个对象比较地址是否一样。
- Object的equals方法存在的意义:让子类重写,以便比较对象的内容是否相同。
- String类的equals方法就是重写Object的,来比较内容。
- equals不能判断基本数据类型,只能比较对象。
- equals底层是通过hashCode比较的
- instanceof关键字来判断对象的真实类型。
package com.gch.d9_api_object;
import java.util.Objects;
public class Student { // extends Object{
private String name;
private char sex;
private int age;
/**
定制相等规则
两个对象的内容一样就认为是相等的
s1.equals(s2)
比较者:s1 == this
被比较者:s2 == o
*/
@Override
public boolean equals(Object o) {
// 1.判断是否是同一个对象比较,如果是返回true
if (this == o) return true;
// 2.判断o是null则返回false 如果o不是学生类型返回false ...Student != o的类型
if (o == null || getClass() != o.getClass()) return false;
// 3.说明o一定是学生类型而且不为null // Objects的equals方法内部会进行非空校验,不等于null才会真正的调用equals方法,更加的安全
Student student = (Student) o; // 如果字符串内容是null调用equals方法会报空指针异常,Objects的equals方法比较更安全
return sex == student.sex && age == student.age && Objects.equals(name, student.name);
}
/**
自己重写equals,自己定制相等规则。
两个对象的内容是一样就认为是相等的
s1.equals(s2)
比较者:s1 == this
被比较着:s2 == o
*/
// @Override
// public boolean equals(Object o){
// // 1.判断o是不是学生类型
// if(o instanceof Student){
// // 2.判断两个对象的内容是否一样
if(this.name.equals(((Student) o).name))
// Student s = (Student)o; // 基本数据类型用==号比较
if(this.name.equals(s.name) && this.age == s.age && this.sex == s.sex){
return true;
}else{
return false;
}
// return this.name.equals(s.name) && this.age == s.age && this.sex == s.sex;
// }else{
// // 学生只能和学生比较,否则结果一定是false
// return false;
// }
// }
public Student() {
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.gch.d9_api_object;
import java.util.Objects;
/**
目标:掌握Object类中equals方法的使用
*/
public class Test2 {
public static void main(String[] args) {
Student s1 = new Student("小李",'男',18);
Student s2 = new Student("小李",'男',18);
// equals默认是比较两个对象的地址是否相同
System.out.println(s1.equals(s2)); // true
// ==比较对象的地址是否相同
System.out.println(s1 == s2); // false
System.out.println(Objects.equals(s1, s2)); // true
}
}
面试题:
package com.object.api;
/**
* @author A.G.H
*/
public class ObjectDemo {
public static void main(String[] args) {
String s = "abc";
StringBuilder sb = new StringBuilder("abc");
System.out.println(s.equals(sb)); // false
// 因为equals方法是被s调用的,而s是字符串
// 所以equals要看String类中的
// 字符串中的equals方法,先判断参数是否为字符串
// 如果是字符串,再比较内部的属性
// 但是如果参数不是字符串,直接返回false
System.out.println(sb.equals(s)); // false
// 因为equals方法是被sb调用的,而sb是StringBuilder
// 所以这里的equals方法要看StringBuilder中的equals方法
// 那么再StringBuilder当中,没有重写equals方法
// 使用的是Object中的
// 在Object当中默认是使用==号比较两个对象的地址值
// 而这里的s和sb记录的地址值是不一样的,所以结果返回false
}
}
3.Object类的方法:clone()方法
对象克隆:
- 把A对象的属性值完全拷贝 / 克隆给B对象,也叫对象拷贝或者是对象复制
package com.object.api;
import java.util.Arrays;
import java.util.StringJoiner;
/**
* @author A.G.H
* 定义User类表示用户
* Cloneable接口,该接口里面没有任何的抽象方法
* 如果一个接口里面没有抽象方法
* 就表示当前的接口是一个标记性接口
* 现在Cloneable接口就表示一旦实现了,那么当前类的对象就可被克隆
* 如果没有实现,就表示当前类的对象不能被克隆
*/
public class User implements Cloneable{
private int id; // 游戏角色编号
private String username; // 用户名
private String password; // 密码
private String path; // 游戏图片
private int[] data; // 游戏进度
public User() {
}
public User(int id, String username, String password, String path, int[] data) {
this.id = id;
this.username = username;
this.password = password;
this.path = path;
this.data = data;
}
/**
* 获取
* @return id
*/
public int getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(int id) {
this.id = id;
}
/**
* 获取
* @return username
*/
public String getUsername() {
return username;
}
/**
* 设置
* @param username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取
* @return password
*/
public String getPassword() {
return password;
}
/**
* 设置
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取
* @return path
*/
public String getPath() {
return path;
}
/**
* 设置
* @param path
*/
public void setPath(String path) {
this.path = path;
}
/**
* 获取
* @return data
*/
public int[] getData() {
return data;
}
/**
* 设置
* @param data
*/
public void setData(int[] data) {
this.data = data;
}
@Override
public String toString() {
return "User{角色编号 = " + id + ", 用户名 = " + username + ", 密码 = " + password +
", 游戏图片 = " + path + ", 进度 = " + Arrays.toString(data) + "}";
}
public String arrToString(){
StringJoiner sj = new StringJoiner(", ","[","]");
for(int i = 0;i < data.length;i++){
sj.add(data[i] + "");
}
return sj.toString();
}
/**
* 对象克隆
* @return:返回克隆之后的对象
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用父类中的clone方法
// 相当于让Java帮我们克隆一个对象,并把克隆之后的对象返回出去。
return super.clone();
}
}
package com.object.api;
/**
目标:掌握Object API: protected object clone() 对象克隆
protected修饰的方法:本类,同包下的其他类,其他包的子类访问(子类访问权限,是让子类去访问的)
*/
public class ObjectCloneDemo {
public static void main(String[] args) throws CloneNotSupportedException {
// 1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1,"zhangsan","1234qwer","gril5",data);
// 2.克隆对象 clone修饰符是protected,Object类是定义在java.lang包下的,
// 如果想要用clone这个方法,只能自己去重写
// 细节:
// 方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
// 书写细节:
// 1.要去重写Object中的clone方法
// 2.要让JavaBean类去实现Cloneable接口
// 3.创建原对象并调用clone方法就可以了
User u2 = (User) u1.clone();
// 3.打印输出
System.out.println(u1);
System.out.println(u2);
}
}
对象克隆的分类:
-
深克隆和浅克隆 / 深拷贝和浅拷贝
浅克隆:
- 首先先创建了一个新的对象,然后会把原来对象记录的数据全部拷贝过来。如果说是基本数据类型,那么就会把记录的数据值拷贝过来;如果是引用数据类型,它就会把记录的地址值拷贝过来。
- 但是这种克隆方式它会有一个小细节,就是对于数组而言,拷贝之后两个数组的地址一样,导致两个数组变量指向同一个数组对象,其中一个对象对数组里面的数据发生了改变,另一个对象再次访问数组的时候就是修改之后的结果。
- 特点:直接拷贝。基本数据类型直接拷贝变量记录的数据值;引用数据类型直接拷贝变量记录的地址值。它有一个专业的称呼叫浅克隆或者叫浅拷贝。
- 不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
- 基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。
- Object类默认的是浅克隆
深克隆:
- 它首先也会创建一个新的对象,如果是基本数据类型,那么跟原来一样它会把变量记录的数据值直接拷贝过来;但是如果是引用数据类型,它就不会直接拷贝地址值了,它会在外面重新再创建一个对象。
- 如果是字符串它会复用字符串常量池里面的,如果说是其他类型的引用数据类型它会创建新的小空间
- 以data数组为例,在浅拷贝当中它是把数组变量记录的地址值直接拷贝过来了,但是在深拷贝中不是这样的,在深拷贝中在外面它会重新创建一个新的数组,新数组的变量记录的就是新数组的地址值,然后把原来数组里面的数据全部拷贝过来。在克隆的对象当中数组变量记录的就是新数组的地址值。所以在深克隆当中,两个对象你操作你的数据,我操作我的数据,两者之间是互相不影响的。
基本数据类型拷贝过来,字符串复用,引用数据类型会重新创建新的
总结:
验证Object中的克隆是浅克隆:
重写clone方法实现深拷贝:
package com.object.clone.deep.copy;
import java.util.Arrays;
import java.util.StringJoiner;
/**
* @author A.G.H
* 定义User类表示用户
* Cloneable接口,该接口里面没有任何的抽象方法
* 如果一个接口里面没有抽象方法
* 就表示当前的接口是一个标记性接口
* 现在Cloneable接口就表示一旦实现了,那么当前类的对象就可被克隆
* 如果没有实现,就表示当前类的对象不能被克隆
*/
public class User implements Cloneable{
private int id; // 游戏角色编号
private String username; // 用户名
private String password; // 密码
private String path; // 游戏图片
private int[] data; // 游戏进度
public User() {
}
public User(int id, String username, String password, String path, int[] data) {
this.id = id;
this.username = username;
this.password = password;
this.path = path;
this.data = data;
}
/**
* 获取
* @return id
*/
public int getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(int id) {
this.id = id;
}
/**
* 获取
* @return username
*/
public String getUsername() {
return username;
}
/**
* 设置
* @param username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取
* @return password
*/
public String getPassword() {
return password;
}
/**
* 设置
* @param password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取
* @return path
*/
public String getPath() {
return path;
}
/**
* 设置
* @param path
*/
public void setPath(String path) {
this.path = path;
}
/**
* 获取
* @return data
*/
public int[] getData() {
return data;
}
/**
* 设置
* @param data
*/
public void setData(int[] data) {
this.data = data;
}
@Override
public String toString() {
return "User{角色编号 = " + id + ", 用户名 = " + username + ", 密码 = " + password +
", 游戏图片 = " + path + ", 进度 = " + Arrays.toString(data) + "}";
}
public String arrToString(){
StringJoiner sj = new StringJoiner(", ","[","]");
for(int i = 0;i < data.length;i++){
sj.add(data[i] + "");
}
return sj.toString();
}
/**
* 重写clone方法实现浅拷贝
* 对象克隆
* @return:返回克隆之后的对象
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
// 调用父类中的clone方法
// 相当于让Java帮我们克隆一个对象,并把克隆之后的对象返回出去。
// 1.先把被克隆对象中的数组获取出来
int[] data = this.data;
// 2.创建新的数组
int[] newData = new int[data.length];
// 3.拷贝数组中的数据
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
// 4.调用父类中的方法克隆对象
User u = (User) super.clone();
// 5.替换克隆出来对象中的数组地址值(因为父类中的克隆方法是浅克隆,所以我们要替换克隆出来对象中的数组地址值)
u.data = newData;
return u;
}
}
package com.object.clone.deep.copy;
/**
目标:掌握Object API: protected object clone() 对象克隆
protected修饰的方法:本类,同包下的其他类,其他包的子类访问(子类访问权限,是让子类去访问的)
*/
public class ObjectCloneDemo {
public static void main(String[] args) throws CloneNotSupportedException {
// 1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1,"zhangsan","1234qwer","gril5",data);
// 2.克隆对象 clone修饰符是protected,Object类是定义在java.lang包下的,
// 如果想要用clone这个方法,只能自己去重写
// 细节:
// 方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
// 书写细节:
// 1.要去重写Object中的clone方法
// 2.要让JavaBean类去实现Cloneable接口
// 3.创建原对象并调用clone方法就可以了
User u2 = (User) u1.clone();
int[] arr = u1.getData();
arr[0] = 100;
// 3.打印输出
System.out.println(u1);
System.out.println(u2);
}
}
导入第三方jar包实现深拷贝:
package com.object.clone.deep.copy;
import com.google.gson.Gson;
/**
目标:掌握Object API: protected object clone() 对象克隆
protected修饰的方法:本类,同包下的其他类,其他包的子类访问(子类访问权限,是让子类去访问的)
*/
public class ObjectCloneDemo {
public static void main(String[] args) throws CloneNotSupportedException {
// 1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1,"zhangsan","1234qwer","gril5",data);
// 补充:
// 在以后的实际开发当中,要进行深克隆是要用到第三方的jar包的
// 什么是第三方:就是不是我们自己写的,也不是Java写的,是别人写的一些大牛写的供我们直接使用的
// 1.将第三方的jar包导入到我们的项目当中
// (在当前模块下新建目录名为lib包,然后把jar包复制到该目录下,最后Add as Library...添加为库即可)
// 2.编写代码
Gson gson = new Gson();
// 把对象变成一个字符串
String s = gson.toJson(u1);
// 再把字符串变回对象就可以了
User u2 = gson.fromJson(s,User.class);
int[] arr = u1.getData();
arr[0] = 100;
// 3.打印输出
System.out.println(u1);
System.out.println(u2);
}
}
三、Objects
Objects概述
- Objects是一个工具类,提供了一些方法去完成一些功能。
- Objects的equals方法内部会进行非空校验,不等于null才会真正的调用equals方法,更加的安全。
- 在Java当中不能用null去调用方法。
- 如果字符串内容是null调用equals方法,运行时候会报空指针异常,Objects的equals方法比较更安全。
Objects的常用API:
public static boolean nonNull(Object obj):判断对象是否不为null,不为null返回true, 跟isNull的结果相反
- 对象进行内容比较的时候建议使用Objects提供的equals方法,虽然比较的结果是一样的,但是更安全。
package com.gch.d10_api_objects;
import java.util.Objects;
/**
目标:掌握Objects类的常用方法:equals
*/
public class Test {
public static void main(String[] args) {
String s1 = null;
String s2 = new String("it");
// System.out.println(s1.equals(s2)); // 运行时报错,NullPointerException空指针异常
System.out.println(Objects.equals(s1 , s2)); // 更安全,结果也更准确 false
// public static boolean isNull(Object obj) 判断变量是否为null ,为null返回true ,反之
System.out.println(Objects.isNull(s1)); // true
System.out.println(s1 == null); // true
System.out.println(Objects.isNull(s2)); // false
System.out.println(s2 == null); // false
}
}
Demo2:
package com.objects.api;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
/**
重写之后的equals方法比较的就是对象内部的属性值了
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
}
package com.objects.api;
import java.util.Objects;
/**
public static boolean equals(Object a,Object b):先做非空判断,比较两个对象
public static boolean isNull(Object obj):判断对象是否为null,为null返回true,反之
public static boolean nonNull(Object obj):判断对象是否不为null,不为null返回true,跟isNull的结果相反
*/
public class ObjectsDemo {
public static void main(String[] args) {
// 1.创建学生类的对象
Student s1 = new Student("zhangsan",23);
Student s2 = new Student("zhangsan",23);
// 2.比较两个对象的属性值是否相同
// 方法细节:
// 1.方法的底层会判断s1是否为null,如果为null,直接返回false
// 2.如果s1不为null,那么就利用s1再次调用equals方法
// 3.此时s1是Student类型,所以最终还是会调用Student中的equals方法
// 如果没有重写,比较地址值;如果重写了,就比较属性值
boolean result = Objects.equals(s1,s2);
System.out.println(result); // true
// 2.public static boolean isNull(Object obj):判断对象是否为null,为null返回true,反之
System.out.println(Objects.isNull(s1)); // false
// 3.public static boolean nonNull(Object obj):判断对象是否不为null,不为null返回true,跟isNull的结果相反
System.out.println(Objects.nonNull(s1)); // true
}
}
四、StringBuilder
StringBuilder概述
- StringBuilder可以看成是一个容器,创建之后里面的内容是可变的。
- 作用:提高字符串的操作效率。
- StringBuider是一个可变的字符串的操作类,我们可以把它看成是一个对象容器,它只占一个对象容器,在一个对象里面完成各种拼接反转操作,所以它的代码比较优雅,性能比较好。
- 使用StringBuilder的核心作用:提高字符串的操作效率,操作字符串的性能要比String要更高(如拼接、修改等)。
- StringBuilder支持链式编程,append方法每次添加完数据后返回StringBuilder对象本身。
- 注意:StringBuilder只是拼接字符串的手段,效率好,最终的目的还是要恢复成String类型。
- 定义字符串还是用String定义,除非要拼接、修改字符串才用StringBuilder。
- 用StringBuilder做字符串拼接之产生一个对象,而String操作字符串一次加号堆内存中产生两个对象。
StringBuilder构造方法:
StringBuilder常用方法
使用StringBuilder的场景:
- 字符串的拼接
- 字符串的反转
package com.gch.d11_api_stringbuilder;
/**
目标:学会使用StringBuilder操作字符串,最终还需要知道它性能好的原因。
*/
public class StringBuilderDemo1 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(); // ""
sb.append("a");
sb.append("b");
sb.append("c");
sb.append(1);
sb.append(false);
sb.append(5.5);
sb.append("abcd");
// 打印对象输出的是属性值即内容而不是地址值,说明重写了toString方法
System.out.println(sb);
StringBuilder sb1 = new StringBuilder();
// 支持链式编程 append方法添加完数据并返回StringBuilder对象本身
// 链式编程:当我们在调用一个方法的时候,不需要用变量接收它的结果,
// 可以继续调用其他方法,说通俗点儿就是依赖前一个方法的结果,再去调用后面的方法
sb1.append("a").append("b").append("c").append("d").append("e");
System.out.println(sb1);
// 反转 public StringBuilder reverse()
System.out.println(sb1.reverse()); // edcba
// public int length() 返回对象内容长度
System.out.println(sb1.length()); // 5
// 注意:StringBuilder只是拼接字符串的手段,效率好
// 最终的目的还是要恢复成String类型。
StringBuilder sb2 = new StringBuilder();
sb2.append("123").append("456");
// 恢复成String 通过toString()就可以实现把StringBuilder转换成String
String rs = sb2.toString();
check(rs);
}
public static void check(String data){
System.out.println(data);
}
}
为什么拼接、反转字符串建议使用StringBuilder?
- StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。
- String:内容是不可变的、拼接字符串性能差。
- 定义字符串使用String。
- 拼接、修改等操作字符串使用StringBuilder
StringBuilder案例1:拼接字符串
package com.gch.d11_api_stringbuilder;
public class StringBuilderTest2 {
public static void main(String[] args) {
// 静态初始化数组
int[] arr1 = null;
System.out.println(toString(arr1)); // null
int[] arr2 = {10,20,30,40,80,90,100};
System.out.println(toString(arr2));
int[] arr3 = {};
System.out.println(toString(arr3)); // []
}
/**
1.定义方法接收任意整型数组,返回数组内容格式
*/
public static String toString(int[] arr){
if(arr != null){
// 2.开始拼接内容
StringBuilder sb = new StringBuilder("[");
for(int i = 0;i < arr.length;i++){
// 如果是这样: sb.append(arr[i]).append(i == arr.length - 1 ? "]" : ", ");
//当数组中没有任何元素,for循环条件i = 0, arr.lenth也是0,0不小于0,循环直接挂了,不进入for循环
// 输出没有任何元素的数组只会输出一个[ ,会出bug
sb.append(arr[i]).append(i == arr.length - 1 ? "" : ", ");
}
sb.append("]");
return sb.toString();
}else{
return null;
}
}
}
StringBuilder案例2:对称字符串
- 什么是对称字符串?
- 正过来反过来都一样的就是对称字符串。
package com.string.api;
/**
需求:键盘接收一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是
对称字符串:123321、111
非对称字符串:123123
*/
public class StringDemo5 {
public static void main(String[] args) {
String str = "racecar";
// 使用方法一判断
if(isPalindrome1(str)){
System.out.println(str + "is a palindrome");
}else{
System.out.println(str + "is not a palindrome");
}
// 使用方法二判断
if(isPalindrome2(str)){
System.out.println(str + "is a palindrome");
}else{
System.out.println(str + "is not a palindrome");
}
}
/**
* 方法一
* 判断该字符串是否是回文字符串 / 对称字符串
* @param str:要判断的字符串
* @return:如果是对称字符串,返回true,否则返回false
*/
public static boolean isPalindrome1(String str){
// 1.定义两个游标,一个在头,一个在尾
int left = 0;
int right = str.length() - 1;
// 2.遍历该字符串,头往前走,尾往后走,判断头和尾对应的字符是否相同,如果是返回true,否则false、
while(left < right){
if(str.charAt(left) != str.charAt(right)){
return false;
}
left++;
right--;
}
// 3.执行到这里说明该字符串头和尾对应的字符都相同,是对称字符串
return true;
}
/**
* 方法二
* 判断该字符串是否是回文字符串 / 对称字符串
* @param str:要判断的字符串
* @return:如果是返回true,否则false
*/
public static boolean isPalindrome2(String str){
// 1.将传进来的字符串反转获得一个新的字符串
// 链式编程
String newStr = new StringBuilder(str).reverse().toString();
// 2.将传进来的字符串与反转后的字符串比较内容是否一致
if(str.equals(newStr)){
// 内容一致返回true
return true;
}else{ // 否则false
return false;
}
}
}
四. StringJoiner类
- 在创建StringJoiner对象的时候,可以指定中间的间隔符号,可以指定拼接的开始符号,还可以指定拼接之后的结束符号
StringJoiner是没有空参构造的
StringJoiner的成员方法:
package com.string.api;
import java.util.StringJoiner;
/**
目标:掌握StringJoiner的构造方法
public StringJoiner(间隔符号):创建一个StringBuilder对象,指定拼接时的间隔符号
StringJoiner成员方法:
public StringJoiner add(添加的内容):添加数据,并返回对象本身
*/
public class StringJoinerDemo1 {
public static void main(String[] args) {
// 1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
// 2.添加元素
sj.add("aaa").add("bbb").add("ccc");
// 3.打印结果
System.out.println(sj); // aaa---bbb---ccc
}
}
package com.string.api;
import java.util.StringJoiner;
/**
目标:掌握StringJoiner的构造方法
public StringJoiner(间隔符号,开始符号,结束符号):创建一个StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号
StringJoiner成员方法:
public int length():返回所有字符的总长度,空白字符也算长度1
public String toString():返回一个字符串(该字符串就是拼接之后的结果)
*/
public class StringJoinerDemo2 {
public static void main(String[] args) {
// 1.创建StringJoiner对象
StringJoiner sj = new StringJoiner(", ","[","]");
// 2.添加元素
sj.add("aaa").add("bbb").add("ccc");
int len = sj.length();
System.out.println(len); // 15
// 3.打印
System.out.println(sj); // [aaa, bbb, ccc]
String str = sj.toString();
System.out.println(str); // [aaa, bbb, ccc]
}
}