常用API-Object、Objects、StringBuilder、StringJoiner类

一、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);
    }
}

对象克隆的分类:

  • 深克隆和浅克隆 / 深拷贝和浅拷贝

浅克隆:

  • 首先先创建了一个新的对象,然后会把原来对象记录的数据全部拷贝过来。如果说是基本数据类型,那么就会把记录的数据值拷贝过来;如果是引用数据类型,它就会把记录的地址值拷贝过来。
  • 但是这种克隆方式它会有一个小细节,就是对于数组而言,拷贝之后两个数组的地址一样,导致两个数组变量指向同一个数组对象,其中一个对象对数组里面的数据发生了改变,另一个对象再次访问数组的时候就是修改之后的结果。
  • 特点:直接拷贝。基本数据类型直接拷贝变量记录的数据值;引用数据类型直接拷贝变量记录的地址值。它有一个专业的称呼叫浅克隆或者叫浅拷贝。
  1. 不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
  2. 基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。
  3. 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的场景:

  1. 字符串的拼接
  2. 字符串的反转

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]
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Surpass余sheng军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值