Java从入门到精通 - 面向对象高级(三)
Java从入门到精通 - 面向对象高级(三)
此笔记参考黑马教程,仅学习使用,如有侵权,联系必删
文章目录
- Java从入门到精通 - 面向对象高级(三)
- 8. 枚举
- 8.1 认识枚举
- 8.1.1 枚举类的格式
- 8.1.2 枚举类的特点
- 代码演示
- 多学一招:使用枚举类实现单例设计模式
- 8.2 枚举的常见应用场景
- 代码演示
- 9. 泛型
- 9.1 认识泛型
- 代码演示
- 9.2 泛型类
- 代码演示
- 9.3 泛型接口
- 代码演示
- 9.4 泛型方法、泛型通配符、上下限
- 9.4.1 通配符
- 9.4.2 上下限
- 代码演示
- 9.5 泛型擦除问题、包装类介绍
- 代码演示
- 10. 常用 API
- 10.1 API 概述
- 10.1.1 什么是 API ?
- 10.1.2 常用 API
- 10.2 Object 类
- 10.2.1 Object 类的作用:
- 10.2.2 Object 类的常见方法
- 代码演示
- 总结
- 10.2.3 Object 类提供的对象克隆方法
- 浅克隆
- 深克隆
- 代码实现
- 总结
- 10.3 Objects
- 代码演示
- 10.4 包装类
- 10.4.1 包装类的其他常见操作
- 代码演示
- 总结
- 10.5 StringBuilder、StringBuffer
- 10.5.1 StringBuilder
- 为啥操作字符串建议使用 StringBuilder,而不是原来学过的 String?
- 案例
- 10.5.2 StringBuffer 与 StringBuilder
- 10.6 StringJoiner
- 代码演示
- 总结
8. 枚举
8.1 认识枚举
- 枚举是一种特殊类
8.1.1 枚举类的格式
修饰符 enum 枚举类名 {名称1, 名称2, ...;其他成员...
}
注意:
- 枚举类中的第一行,只能写一些合法的标识符(名称),多个名称用逗号隔开
- 这些名称,本质是常量,每个常量都会记住枚举类的一个对象
8.1.2 枚举类的特点
package Advanced.h_enum;public enum A {// 注意:枚举类的第一行必须罗列的是枚举对象的名字X, Y ,Z;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
Compiled from "A.java"
public final class Advanced.h_enum.A extends java.lang.Enum<Advanced.h_enum.A> {public static final Advanced.h_enum.A X;public static final Advanced.h_enum.A Y;public static final Advanced.h_enum.A Z;public static Advanced.h_enum.A[] values();public static Advanced.h_enum.A valueOf(java.lang.String);public java.lang.String getName();public void setName(java.lang.String);static {};
}
- 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象
- 枚举类的构造器都是是有的(写不写都只能是私有的),因此,枚举类对外不能创建对象
- 枚举都是最终类,不可以被继承
- 枚举类中,从第二行开始,可以定义类的其他各种成员
- 编译器为枚举类新增了几个方法,并且枚举类都是继承:java.lang.Enum 类的,从 enum 类也会继承到一些方法
代码演示
- A.java
package Advanced.h_enum;public enum A {// 注意:枚举类的第一行必须罗列的是枚举对象的名字X, Y, Z;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
- B.java
package Advanced.h_enum;// 拓展:抽象枚举
public enum B {X() {@Overridepublic void go() {}}, Y("张三") {@Overridepublic void go() {System.out.println(getName() + "在跑~~~");}};private String name;B() {}B(String name) {this.name = name;}public abstract void go();public String getName() {return name;}public void setName(String name) {this.name = name;}
}
- Test.java
package Advanced.h_enum;public class Test {public static void main(String[] args) {// 目标:认识枚举A a1 = A.X;System.out.println(a1);// 1. 枚举类的构造器是私有的,不能对外创建对象
// A a = new A(); // 报错// 2. 枚举类的第一行都是常量,记住的是枚举类的对象A a2 = A.Y;// 3. 枚举类提供一些额外的APIA[] as = A.values(); // 拿到全部对象A a3 = A.valueOf("Z"); // 根据常量名得到枚举对象System.out.println(a3.name()); // ZSystem.out.println(a3.ordinal()); // 索引 2System.out.println("-----------------------------");B y = B.Y;y.go(); // 张三在跑~~~}
}
多学一招:使用枚举类实现单例设计模式
public enum C {X; // 单例
}
8.2 枚举的常见应用场景
- 用来表示一组信息,然后作为参数进行传输
选择定义一个一个的常量表示一组信息,并作为参数传输
- 参数值不受约束
选择定义枚举表示一组信息,并作为参数传输
- 代码可读性好,参数值得到了约束,对使用者更友好,建议使用
代码演示
- Constant.java
package Advanced.h_enum.enum2;public class Constant {public static final int BOY = 0;public static final int GIRL = 1;
}
- Constant2.java
package Advanced.h_enum.enum2;public enum Constant2 {BOY, GIRL;
}
- Test.java
package Advanced.h_enum.enum2;public class Test {public static void main(String[] args) {// 目标:掌握枚举的应用场景:做信息标志和分类
// check(1);
// check(Constant.BOY);check(Constant2.BOY);}public static void check(Constant2 sex) {switch (sex) {case BOY:System.out.println("展示一些美女图、游戏信息~~~");break;case GIRL:System.out.println("展示一些帅哥图~~~");break;}}// public static void check(int sex) {
// switch (sex){
// case Constant.BOY:
// System.out.println("展示一些美女图、游戏信息~~~");
// break;
// case Constant.GIRL:
// System.out.println("展示一些帅哥图~~~");
// break;
// }
// }}
9. 泛型
9.1 认识泛型
- 定义类、接口、方法时,同时声明了一个或者多个类型变量(如:),称为泛型类、泛型接口、泛型方法,它们统称为泛型
public class ArrayList<E>{...
}
- 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常
- 泛型的本质:把具体的数据类型作为参数传给类型变量(看源码)
代码演示
package Advanced.i_generics;import java.util.ArrayList;public class Test1 {public static void main(String[] args) {// 目标:认识泛型ArrayList list = new ArrayList();list.add("java1");list.add("java2");list.add("java3");list.add(new Cat());for (int i = 0; i < list.size(); i++) {String e = (String) list.get(i);System.out.println(e);}System.out.println("---------------------------------");ArrayList<String> list1 = new ArrayList<>();list1.add("java1");list1.add("java2");list1.add("java3");
// list1.add(new Cat()); // 报错for (int i = 0; i < list1.size(); i++) {String e = list1.get(i);System.out.println(e);}}
}class Cat {}
9.2 泛型类
修饰符 class 类名<类型变量, 类型变量, ...>{}
public class ArrayList<E>{...
}
注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
代码演示
- MyArrayList.java
package Advanced.i_generics.generics_class;// 泛型类
public class MyArrayList<E> {private Object[] arr = new Object[10];private int size; // 记录当前位置public boolean add(E e) {arr[size++] = e;return true;}public E get(int index) {return (E) arr[index];}
}
- MyClass2.java
package Advanced.i_generics.generics_class;public class MyClass2<E, T> {public void put(E e, T t) {}
}
- Animal.java
package Advanced.i_generics.generics_class;public class Animal {
}
- Cat.java
package Advanced.i_generics.generics_class;public class Cat extends Animal {
}
- Dog.java
package Advanced.i_generics.generics_class;public class Dog extends Animal{
}
- MyClass3.java
package Advanced.i_generics.generics_class;public class MyClass3 <E extends Animal>{
}
- Test.java
package Advanced.i_generics.generics_class;public class Test {public static void main(String[] args) {// 目标:掌握泛型类的定义和使用MyArrayList<String> list = new MyArrayList<>();list.add("java1");list.add("java2");list.add("java3");String ele = list.get(1);System.out.println(ele); // java2MyClass2<Cat, String> c2 = new MyClass2<>();MyClass3<Animal> c3 = new MyClass3<>();MyClass3<Dog> c4 = new MyClass3<>();}
}
9.3 泛型接口
修饰符 interface 接口名<类型变量, 类型变量, ...> {}
public interface A<E> {...
}
- 注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
泛型接口就是给实现类实现的,实现类在实现泛型接口的时候可以声明一个数据类型上来,然后实现类重写的这些方法都将是针对于该类型的操作了
代码演示
- Student.java
package Advanced.i_generics.generics_interface;public class Student {
}
- Teacher.java
package Advanced.i_generics.generics_interface;public class Teacher {
}
- Data.java
package Advanced.i_generics.generics_interface;import java.util.ArrayList;// 泛型接口
public interface Data<T> {void add(T t);ArrayList<T> getByName(String name);
}
- StudentData.java
package Advanced.i_generics.generics_interface;import java.util.ArrayList;public class StudentData implements Data<Student> {@Overridepublic void add(Student student) {}@Overridepublic ArrayList<Student> getByName(String name) {return null;}
}
- TeacherData.java
package Advanced.i_generics.generics_interface;import java.util.ArrayList;public class TeacherData implements Data<Teacher> {@Overridepublic void add(Teacher teacher) {}@Overridepublic ArrayList<Teacher> getByName(String name) {return null;}
}
- Test.java
package Advanced.i_generics.generics_interface;public class Test {public static void main(String[] args) {// 目标:掌握泛型接口的定义和使用// 场景:系统需要处理学生和老师的数据,需要提供2个功能:保存对象数据、根据名称查询数据}
}
9.4 泛型方法、泛型通配符、上下限
修饰符 <类型变量, 类型变量, ...> 返回值类型 方法名(形参列表) {}
public static <T> void test(T t) {}
9.4.1 通配符
- 就是
?
,可以在 “使用泛型” 的时候代表一切类型;E T K V 是在定义泛型的时候使用
9.4.2 上下限
- 泛型上限:
? extends Car
------ ? 能接收的必须是 Car 或者其子类 - 泛型下限:
? super Car
------ ? 能接收的必须是 Car 或者其父类
代码演示
- Car.java
package Advanced.i_generics.generics_method;public class Car {
}
- BMW.java
package Advanced.i_generics.generics_method;public class BMW extends Car{
}
- BENZ.java
package Advanced.i_generics.generics_method;public class BENZ extends Car{
}
- Dog.java
package Advanced.i_generics.generics_method;public class Dog {
}
- Test.java
package Advanced.i_generics.generics_method;import java.util.ArrayList;public class Test {public static void main(String[] args) {// 目标:掌握泛型方法的定义和使用String rs = test("java");System.out.println(rs);Dog d = test(new Dog());System.out.println(d);// 需求:所有的汽车可以一起参加比赛ArrayList<Car> cars = new ArrayList<>();cars.add(new BMW());cars.add(new BENZ());go(cars);ArrayList<BMW> bmws = new ArrayList<>();bmws.add(new BMW());bmws.add(new BMW());go(bmws);ArrayList<BENZ> benzs = new ArrayList<>();benzs.add(new BENZ());benzs.add(new BENZ());go(benzs);// ArrayList<Dog> dogs = new ArrayList<>();
// dogs.add(new Dog());
// dogs.add(new Dog());
// go(dogs); // 报错}// ? 通配符,在使用泛型的时候可以代表一切类型 ? extends Car 称为上限继承 ? super Car 称为下限继承public static void go(ArrayList<? extends Car> cars) {}// public static <T extends Car> void go(ArrayList<T> cars){
//
// }// 泛型方法public static <T> T test(T t) {return t;}
}
9.5 泛型擦除问题、包装类介绍
- 泛型是工作在编译阶段的,一旦程序编译成 class 文件,class 文件中就不存在泛型了,这就是泛型擦除
- 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
代码演示
package Advanced.i_generics.generics_attention;import java.util.ArrayList;public class Test {public static void main(String[] args) {// 目标:理解泛型的注意事项// 1. 泛型是工作在编译阶段的,一旦程序编译成 class 文件,class 文件中就不存在泛型了,这就是泛型擦除ArrayList<String> list = new ArrayList<>();list.add("java1");list.add("java2");list.add("java3");String rs = list.get(2);System.out.println(rs);// 2. 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
// ArrayList<int> list1 = new ArrayList<>(); // 报错
// ArrayList<double> list2 = new ArrayList<>(); // 报错ArrayList<Integer> list1 = new ArrayList<>();list1.add(12);ArrayList<Double> list2 = new ArrayList<>();list2.add(23.3);}
}
10. 常用 API
10.1 API 概述
10.1.1 什么是 API ?
- API(Application Programming interface):应用程序编程接口
- 就是 Java 帮我们已经写好一些程序,如:类、方法等,我们直接拿过来用就可以解决一些问题
10.1.2 常用 API
10.2 Object 类
10.2.1 Object 类的作用:
- Object 类是 Java 中所有类的祖宗类,因此,Java 中所有类的对象都可以直接使用 Object 类中提供的一些方法
10.2.2 Object 类的常见方法
方法名称 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式 |
public boolean equals(Object o) | 判断两个对象是否相等 |
protected Object clone() | 对象克隆 |
toString 存在的意义:toString() 方法存在的意义就是为了被子类重写,以便返回对象具体的内容
equals 存在的意义:直接比较两个对象的地址是否相同完全可以用 “==” 替代 equals,equals 存在的意义就是为了被子类重写,以便子类自己来定制比较规则(比如比较对象内容)
代码演示
- Student.java
package Advanced.j_api_object.api_object;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;}// 重写equals方法,比较两个对象的内容一样就返true// 比较者:s2 == this// 被比较者:s1 == o@Overridepublic boolean equals(Object o) {// 1. 判断两个对象是否地址一样,一样直接返回trueif (this == o) return true;// 2. 判读o是null直接返回false,或者比较者的类型与被比较者的类型不一样,直接返回falseif (o == null || getClass() != o.getClass()) return false;// 3. o不是null,且o一定是学生类型的对象,开始比较内容Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
- Test.java
package Advanced.j_api_object.api_object;public class Test {public static void main(String[] args) {// 目标:掌握Object类提供的常用方法Student s1 = new Student("张三", 23);
// System.out.println(s1.toString());System.out.println(s1); // Student{name='张三', age=23}Student s2 = new Student("张三", 23);System.out.println(s2.equals(s1)); // trueSystem.out.println(s2 == s1); // false}
}
总结
- Object 中 toString 方法的作用是什么?存在的意义是什么?
- 基本作用:返回对象的字符串形式
- 存在的意义:让子类重写,以便返回子类对象的内容
- Object 中 equals 方法的作用是什么?存在的意义是什么?
- 基本作用:默认是比较两个对象的地址是否相等
- 存在的意义:让子类重写,以便用于比较对象的内容是否相同
10.2.3 Object 类提供的对象克隆方法
方法名 | 说明 |
---|---|
protected Object clone() | 对象克隆 |
- 当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回
浅克隆
- 拷贝出的新对象,与原对象中的数据一模一样(应用类型拷贝的只是地址)
深克隆
- 对象中基本类型的数据直接拷贝
- 对象中的字符串数据拷贝的还是地址
- 对象中还包含的其他对象,不会拷贝地址,会创建新对象
代码实现
- User.java
package Advanced.j_api_object.api_object;// Cloneable是一个标记接口
// 可以理解为是一种规则
public class User implements Cloneable {private int id; // 编号private String username; // 用户名private String password; // 密码private double[] scores; // 分数public User() {}public User(int id, String username, String password, double[] scores) {this.id = id;this.username = username;this.password = password;this.scores = scores;}@Overrideprotected Object clone() throws CloneNotSupportedException {// super去调用父类Object中的clone方法User u2 = (User) super.clone();u2.scores = u2.scores.clone();return u2;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public double[] getScores() {return scores;}public void setScores(double[] scores) {this.scores = scores;}
}
- Test.java
package Advanced.j_api_object.api_object;public class Test2 {public static void main(String[] args) throws CloneNotSupportedException {// 目标:掌握Object类提供的对象克隆的方法// 1. protected Object clone():对象克隆User u1 = new User(1, "zhangsan", "wo666", new double[]{99.0, 99.5});User u2 = (User) u1.clone();System.out.println(u1.getId()); // 1System.out.println(u1.getUsername()); // zhangsanSystem.out.println(u1.getPassword()); // wo666System.out.println(u1.getScores()); // [D@b4c966aSystem.out.println(u2.getId()); // 1System.out.println(u2.getUsername()); // zhangsanSystem.out.println(u2.getPassword()); // wo666System.out.println(u2.getScores()); // [D@2f4d3709}
}
总结
- 什么是对象克隆?
- 当某个对象调用 clone 方法时,会复制一个一模一样的新对象返回
- 什么是浅克隆?
- 拷贝出的新对象,与原对象中的数据一模一样(应用类型拷贝的只是地址)
- 什么是深克隆?
- 对象中基本类型的数据直接拷贝
- 对象中的字符串数据拷贝的还是地址
- 对象中还包含的其他对象,不会拷贝地址,会创建新对象
10.3 Objects
- Objects 是一个工具类,提供了很多操作对象的静态方法给我们使用
方法名称 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 先做非空判断,再比较两个对象 |
public static boolean isNull(Objetc obj) | 判断对象是否为 null,为 null 则返回 true,反之 |
public static boolean nonNull(Object obj) | 判断对象是否不为 null,不为 null 则返回 true,反之 |
源码分析
public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b));
}
代码演示
package Advanced.j_api_object.api_objects;import java.util.Objects;public class Test {public static void main(String[] args) {// 目标:掌握Objects类提供的常用方法String s1 = null;String s2 = "itfeng";// System.out.println(s1.equals(s2)); // 报空指针异常System.out.println(Objects.equals(s1, s2)); // falseSystem.out.println(Objects.isNull(s1)); // trueSystem.out.println(Objects.isNull(s2)); // falseSystem.out.println(Objects.nonNull(s1)); // falseSystem.out.println(Objects.nonNull(s2)); // true}
}
10.4 包装类
- 包装类就是把基本类型的数据包装成对象
基本数据类型 | 对应的包装类(引用数据类型) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
基本类型的数据包装成对象的方案 |
---|
public Integer(int value):已过时 |
public static Integer valueOf(int i) |
自动装箱:基本数据类型可以自动转换为包装类型
自动拆箱:包装类型可以自动转换为基本数据类型
10.4.1 包装类的其他常见操作
- 可以把基本类型的数据转换成字符串类型
public static String toString(double d)
public String toString()
- 可以把字符串类型的数值转换成数值本身对应的数据类型
public static int parseint(String s)
public static Integer valueOf(String s)
代码演示
package Advanced.k_package.integer;import java.util.ArrayList;public class Test {public static void main(String[] args) {// 目标:掌握包装类的使用
// Integer a1 = new Integer(12); // 过时Integer a2 = Integer.valueOf(12);System.out.println(a2); // 12// 自动装箱:可以自动把基本类型的数据转换成对象Integer a3 = 12;// 自动拆箱:可以自动把包装类型的对象转换成对应的基本数据类型int a4 = a3;// 泛型和集合不支持基本数据类型,只能支持引用数据类型
// ArrayList<int> list = new ArrayList<>(); // 报错ArrayList<Integer> list = new ArrayList<>();list.add(12); // 自动装箱list.add(13); // 自动装箱int rs = list.get(1); // 自动拆箱System.out.println("--------------------------------");// 1. 把基本类型的数据转换成字符串类型Integer a = 23;String rs1 = Integer.toString(a);System.out.println(rs1 + 1); // 231String rs2 = a.toString();System.out.println(rs2 + 1); // 231String rs3 = a + "";System.out.println(rs3 + 1); // 231// 2. 把字符串类型的数值转换成数值本身对应的数据类型String ageStr = "29";
// int ageI = Integer.parseInt(ageStr);int ageI = Integer.valueOf(ageStr);System.out.println(ageI + 1); // 30String scoreStr = "99.5";
// double score = Double.parseDouble(scoreStr);double score = Double.valueOf(scoreStr);System.out.println(score + 0.5); // 100.0}
}
总结
- 为什么要有包装类,包装类有哪些?
- 包装类就是把基本类型的数据包装成对象
- 泛型和集合不支持基本数据类型,只能支持引用数据类型
- Byte、Short、Integer、Long、Character、Float、Double、Boolean
- 包装类提供了哪些常见的功能?
- 可以把基本类型的数据转换成字符串类型
- 可以把字符串类型的数值转换成数值本身对应的数据类型
10.5 StringBuilder、StringBuffer
10.5.1 StringBuilder
- StringBuilder 代表可变字符串对象,相当于是一个容器,它里面装的字符串是可以改变的,就是用来操作字符串的
- 好处:StringBuilder 比 String 更适合做字符串的修改操作,效率会更高,代码也会更简洁
构造器 | 说明 |
---|---|
public StringBuilder() | 创建一个空白的可变的字符串对象,不包含任何内容 |
public StringBuilder(String str) | 创建一个指定字符串内容的可变字符串对象 |
方法名称 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加数据并返回 StringBuilder 对象本身 |
public StringBuilder reverse() | 将对象的内容反转 |
public int length() | 返回对象内容长度 |
public String toString() | 通过 toString() 就可以实现把 StringBuilder 转换成 String |
- 代码演示
package Advanced.l_stringBuilder;public class Test1 {public static void main(String[] args) {// 目标:搞清楚StringBuilder的用法和作用
// StringBuilder s = new StringBuilder();StringBuilder s = new StringBuilder("itfeng");// 1. 拼接内容s.append(12);s.append("FENG");s.append(true);// 支持链式编程s.append(666).append("FENG2").append(666);// 2. 反转操作s.reverse();System.out.println(s); // 6662GNEF666eurtGNEF21gnefti// 3. 返回字符串的长度System.out.println(s.length()); // 27// 4. 把StringBuilder对象又转换成String类型String rs = s.toString();System.out.println(rs); // 6662GNEF666eurtGNEF21gnefti}
}
为啥操作字符串建议使用 StringBuilder,而不是原来学过的 String?
- 因为使用 String 频繁操作字符串的话,比如拼接、修改等,效率是比较低的,而使用 StringBuilder 来频繁操作字符串的话效率非常高
- 对于字符串相关的操作,如频繁的拼接、修改等,建议用 StringBuilder,效率更高!
- 注意:如果操作字符串较少,或者不需要操作,以及定义字符串变量,还是建议用 String
代码演示
package Advanced.l_stringBuilder;public class Test2 {public static void main(String[] args) {// 目标:掌握StringBuilder的好处// 需求:拼接100万次abc// 先用String测试看看性能
// String rs = "";
// for (int i = 1; i < 1000000; i++) {
// rs = rs + "abc";
// }
// System.out.println(rs);// 使用StringBuilder演示StringBuilder sb = new StringBuilder();for (int i = 1; i < 1000000; i++) {sb.append("abc");}System.out.println(sb);}
}
案例
需求:
设计一个方法,用于返回任意整型数组的内容,要求返回的数组内容格式如:
[11, 22, 33]
分析:
- 方法是否需要接收数据? 需要接收整型数组
- 方法是否需要返回数据? 需要返回拼接后的结果
- 方法内部:遍历数组的数据,把遍历到的数据都拼接起来,此时使用 StringBuilder 来完成拼接
代码实现
package Advanced.l_stringBuilder;public class Test3 {public static void main(String[] args) {// 目标:完成遍历数组内容,并拼接成指定格式的案例System.out.println(getArrayData(new int[]{11, 22, 33}));}public static String getArrayData(int[] arr) {// 1. 判断arr是否为nullif (arr == null) {return null;}// 2. arr数组对象存在。arr = [11, 22, 33]StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if (i == arr.length - 1) {sb.append(arr[i]);} else {sb.append(arr[i]).append(", ");}}sb.append("]");return sb.toString();}
}
10.5.2 StringBuffer 与 StringBuilder
注意:
- StringBuffer 的用法与 StringBuilder 是一模一样的
- 但 StringBuilder 是线程不安全的,StringBuffer 是线程安全的
10.6 StringJoiner
- JDK8开始才有的,跟 StringBulider 一样也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的
- 好处:不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁
构造器 | 说明 |
---|---|
public StringJoiner(间隔符号) | 创建一个 StringJoiner 对象,指定拼接时的间隔符号 |
public StringJoiner(间隔符号, 开始符号, 结束符号) | 创建一个 StringJoiner 对象,指定拼接时的间隔符号、开始符号、结束符号 |
方法名称 | 说明 |
---|---|
public StringJoiner add (添加的内容) | 添加数据,并返回对象本身 |
public int length() | 返回长度(字符出现的个数) |
public String toString() | 返回一个字符串(该字符串就是拼接之后的结果) |
代码演示
package Advanced.m_stringjoiner;import java.util.StringJoiner;public class Test {public static void main(String[] args) {// 目标:掌握StringJoiner的使用
// StringJoiner s = new StringJoiner(", "); // 间隔符StringJoiner s = new StringJoiner(", ", "[", "]"); // 间隔符s.add("java1");s.add("java2");s.add("java3");System.out.println(s); // [java1, java2, java3]System.out.println(getArrayData(new int[]{11, 22, 33})); // [11, 22, 33]}public static String getArrayData(int[] arr) {// 1. 判断arr是否为nullif (arr == null) {return null;}// 2. arr数组对象存在。arr = [11, 22, 33]StringJoiner s = new StringJoiner(", ", "[", "]");for (int i = 0; i < arr.length; i++) {s.add(arr[i] + "");}return s.toString();}
}
总结
- StringJoiner 是啥?使用它有什么好处?
- 跟 StringBulider 一样也是用来操作字符串的,也可以看成是一个容器,创建之后里面的内容是可变的
- 好处:不仅能提高字符串的操作效率,并且在有些场景下使用它操作字符串,代码会更简洁