9~10 异常、常用类

9 异常

9.1 异常三连 try-catch-finally

package com.liweixiao.test01;

import java.util.Scanner;

/**
 * @author:LiWeixiao
 * @date:2022/11/10
 * @description:
 */
public class Test {
    public static void main(String[] args) {
        try {
            //实现一个功能,键盘输入两个数,求商
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第一个数:");
            int num1=sc.nextInt();
            System.out.println("请输入第二个数:");
            int num2=sc.nextInt();
            System.out.println("商:"+num1/num2);
        } catch (Exception e) {
            System.out.println("程序出现异常。");
            e.printStackTrace();
        } finally {
            System.out.println("finally的程序");
        }
        System.out.println("异常之后的程序");
    }
}

【1】在什么情况下,try-catch后面的代码不执行?
(1)throw抛出异常的情况
(2)catch中没有正常的进行异常捕获
(3)在try中遇到return
【2】怎么样才可以将 try-catch后面的代码 必须执行?
只要将必须执行的代码放入finally中,那么这个代码无论如何一定执行。
【3】return和finally执行顺序?
先执行finally最后执行return
【4】什么代码会放在finally中呢?
关闭数据库资源,关闭IO流资源,关闭socket资源。
【5】有一句话代码很厉害,它可以让finally中代码不执行!
System.exit(0);//终止当前的虚拟机执行

9.2 异常分类

检查异常、运行时异常

图片来自网络

9.3 throw和throws

package com.liweixiao.test01;

import java.util.Scanner;

/**
 * @author:LiWeixiao
 * @date:2022/11/10
 * @description:
 */
public class Test02 {
    public static void main(String[] args) throws Exception {
        devide();
        System.out.println("异常之后的程序");
    }

    public static void devide() throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入第一个数:");
        int num1=sc.nextInt();
        System.out.println("请输入第二个数:");
        int num2=sc.nextInt();
        if(num2 == 0){
            throw new Exception();
        }else {
            System.out.println("商:"+ num1/num2);
        }
    }
}

总结:
throw和throws的区别:
(1)位置不同:
throw:方法内部
throws: 方法的签名处,方法的声明处
(2)内容不同:
throw+异常对象(检查异常,运行时异常)
throws+异常的类型(可以多个类型,用,拼接)
(3)作用不同:
throw:异常出现的源头,制造异常。
throws:在方法的声明处,告诉方法的调用者,这个方法中可能会出现我声明的这些异常。然后调用者对这个异常进行处理:
要么自己处理要么再继续向外抛出异常

9.4 重载和重写的异常

图片来自网络

9.5 自定义异常

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/11/11
 * @description:自定义运行时异常
 */
public class MyExceptionRun extends RuntimeException{

    //序列号
    static final long serialVersionUID = -703489719L;

    public MyExceptionRun(){}
    public MyExceptionRun(String msg){
        super(msg);
    }
}
package com.liweixiao.test01;

import java.util.Scanner;

/**
 * @author:LiWeixiao
 * @date:2022/11/11
 * @description:
 */
public class Test03 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入第一个数:");
        int num1=sc.nextInt();
        System.out.println("请输入第二个数:");
        int num2=sc.nextInt();
        if(num2 == 0){
            throw new MyExceptionRun("除数不能为0");
        }else {
            System.out.println("商:"+ num1/num2);
        }
    }
}

如果继承的是运行时异常,那么在使用的时候无需额外处理。
如果继承的是检查异常,那么使用的时候需要try-catch捕获或者throws向上抛。

10 常用类

10.1 引入

10.1.1 包装类

1.以前定义变量,经常使用基本数据类型。
对基本数据类型进行了一个封装,产生了一个新的类,包装类。

2.对应关系
基本数量类型 对应的包装类 继承关系
byte Byte ->Number->Object
short Short ->Number->Object
int Integer ->Number->Object
long Long ->Number->Object
float Float ->Number->Object
double Double ->Number->Object
char Character ->Object
boolean Boolean ->Object

3.已经有了基本数据类型,为什么要封装为包装类?
(1)java语言 面向对象的语言,最擅长的操作各种各样的类
(2)数组,int[] String[] double[] Student[]
集合,只能装引用数据类型的数据

4.是不是有了包装类以后就不用基本数据类型了?
不是。

10.1.2 Integer

1.直接使用,无需导包java.lang
2.类的继承关系,->Number->Object
3.实现接口,Serializable、Comparable
4.被final修饰,不能有子类,不能被继承
5.包装类是对基本数据类型的封装,对int类型封装产生了Integer
6.从jdk1.0开始
7.重要属性,MAX_VAIUE、MIN_VALUE

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test01 {
    public static void main(String[] args) {
        //属性
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MIN_VALUE);
        //物极必反
        System.out.println(Integer.MAX_VALUE+1);
        System.out.println(Integer.MIN_VALUE-1);

    }
}

8.没有空参构造器
(1)int类型作为构造器的参数

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        //构造器
        Integer i1 = new Integer(12);
        System.out.println(i1.toString());
    }
}

(2)String类型作为构造器的参数

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        //构造器
        Integer i2 = new Integer("123");
        System.out.println(i2);
    }
}

9.包装类特有的机制:自动装箱、自动拆箱

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test03 {
    public static void main(String[] args) {
        //自动装箱,int->Integer
        Integer i=12;
        System.out.println(i);
        //自动拆箱,Integer->int
        Integer i2=new Integer(23);
        int i3=i2;
        System.out.println(i3);
    }
}

(1)JDK1.5以后新出的特性
(2)将基本数据类型 和 包装类 自动转换
10.常用方法
compareTo、equals、intValue、parseInt、toString

package com.liweixiao.test01;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test04 {
    public static void main(String[] args) {
        //compareTo,只返回三个值:1,0,-1
        Integer i1=new Integer(10);
        Integer i2=new Integer(1);
        System.out.println(i1.compareTo(i2));//1

        //equals,比较的是底层封装的哪个value值
        //Integer对象是通过new关键字创建的对象
        Integer i3=new Integer(11);
        Integer i4=new Integer(11);
        System.out.println(i3 == i4);//false,因为==比较的是地址
        System.out.println(i3.equals(i4));//ture
        //Integer对象通过自动装箱完成
        Integer i5=10;//如果在-128~127之间返回数,否则返回Integer对象
        Integer i6=10;
        System.out.println(i5==i6);//ture
        System.out.println(i5.equals(i6));//ture
        /*如果自动装箱值在-128~127之间,那么比较的是具体的数值,
        否则比较的是对象的地址*/

        //intValue,将Integer转换为int类型
        Integer i7=130;
        int i8=i7.intValue();
        int i9=i7;//intValue
        System.out.println(i8);//130
        System.out.println(i9);//130

        //parseInt,将String转换为int
        int i10 = Integer.parseInt("123");
        System.out.println(i10);//123

        //toString,将Integer转换为String
        Integer i11=130;
        String s = i11.toString();
        System.out.println(s);
    }
}

valueOf方法的底层

以上图片来自网络

10.2 日期类

10.2.1 java.util.Date

package com.liweixiao.test02;

import java.util.Date;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test01 {
    public static void main(String[] args) {
        //java.util.Date
        Date d = new Date();
        System.out.println(d);//Tue Dec 06 15:15:53 CST 2022
        System.out.println(d.toString());
        System.out.println(d.toGMTString());//6 Dec 2022 07:16:43 GMT
        System.out.println(d.toLocaleString());//2022-12-6 15:27:38
        System.out.println(d.getYear());//122
        System.out.println(d.getMonth());//11
        System.out.println(d.getTime());//1670312040606
        System.out.println(System.currentTimeMillis());//1670312272713
        /*
        (1)以后获取时间用getTime()还是currentTimeMillis()
        currentTimeMillis是静态的,可以类名.方法名直接调用
        (2)public static native long currentTimeMillis();
        native本地方法,没有方法体,因为具体实现不是通过java写的
        (3)使用这个方法,可以计算耗时毫秒数
        */
    }
}

10.2.2 java.sql.Date

package com.liweixiao.test02;

import java.sql.Date;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        //java.sql.Date
        Date d = new Date(1670312040606L);
        System.out.println(d);//2022-12-06
        /*
        java.util.Date有年月日时分秒,java.sql.Date只有年月日
        java.sql.Date继承java.util.Date
        */

        //util->sql
        java.util.Date date1 = new java.util.Date();
        //方式1:向下转型
        //Date date2 =(Date) date1;//java.util.Date cannot be cast to java.sql.Date
        Date date2 =new Date(1670312040606L);
        System.out.println(date2);
        //方式2:利用构造器
        Date date3 = new Date(date1.getTime());
        System.out.println(date3);

        //sql->util
        //方式1:父类引用指向子类对象
        java.util.Date date4=d;
        System.out.println(date4);

        //String->sql.Date
        Date date5 = Date.valueOf("2022-12-05");
        System.out.println(date5);
    }
}

10.2.3 日期转换

package com.liweixiao.test02;

import java.util.Date;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test04 {
    public static void main(String[] args) {
        /*
        String->java.util.Date
        分解:1.String->java.sql.Date
        2.java.sql.Date->java.util.Date
        */
        java.sql.Date date1=java.sql.Date.valueOf("2022-12-06");//只能是年-月-日格式
        System.out.println(date1);
        Date date2=date1;
        System.out.println(date2);
    }
}

日期格式:

以上图片来自网络

引入新的类SimpleDateFormat

package com.liweixiao.test02;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test05 {
    public static void main(String[] args) {
        //日期转换
        //父类引用指向子类对象,SimpleDateFormat extends DateFormat
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        //String->java.util.Date
        try {
            Date d = df.parse("2022-12-6 17:10:11");
            System.out.println(d);//Tue Dec 06 17:10:11 CST 2022
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        //java.util.Date->String
        String s = df.format(new Date());
        System.out.println(s);//2022-12-06 17:27:04

        Date date =new Date();
        System.out.println(date.toString());//Tue Dec 06 18:52:37 CST 2022
        System.out.println(date.toGMTString());//6 Dec 2022 10:52:37 GMT
        System.out.println(date.toLocaleString());//2022-12-6 18:52:37
    }
}

10.2.4 Calendar

package com.liweixiao.test02;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * @author:LiWeixiao
 * @date:2022/12/6
 * @description:
 */
public class Test06 {
    public static void main(String[] args) {
        //Calendar是抽象类,不能创建对象
        Calendar cal1 = new GregorianCalendar();
        System.out.println(cal1);
        Calendar cal2 = Calendar.getInstance();
        System.out.println(cal2);
        /*
        java.util.GregorianCalendar
        [time=1670338495911,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo
        [id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],
        firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,
        YEAR=2022,MONTH=11,WEEK_OF_YEAR=50,WEEK_OF_MONTH=2,DAY_OF_MONTH=6,DAY_OF_YEAR=340,
        DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=10,HOUR_OF_DAY=22,
        MINUTE=54,SECOND=55,MILLISECOND=911,ZONE_OFFSET=28800000,DST_OFFSET=0]
        */

        //常用的方法
        //get方法,传入参数,Calendar中定义的常量
        System.out.println(cal1.get(Calendar.YEAR));
        System.out.println(cal1.get(Calendar.MONTH));//从0开始
        System.out.println(cal1.get(Calendar.DATE));
        System.out.println(cal1.get(Calendar.DAY_OF_WEEK));//周日是第1天
        System.out.println(cal1.getMaximum(Calendar.DATE));//获取当月日期的最大
        System.out.println(cal1.getMinimum(Calendar.DATE));//获取当月日期的最小

        //set方法,可以改变Calendar中的内容
        cal1.set(Calendar.YEAR,2020);
        cal1.set(Calendar.MONTH,11);
        cal1.set(Calendar.DATE,11);
        System.out.println(cal1);

        //String->Calendar
        //分解:String->java.sql.Date
        java.sql.Date date = java.sql.Date.valueOf("2000-1-1");
        //java.sql.Date->Calendar
        cal1.setTime(date);
        System.out.println(cal1);
    }
}

练习,需求如下:

以上图片来自网络

package com.liweixiao.test02;

import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;

/**
 * @author:LiWeixiao
 * @date:2022/12/8
 * @description:
 */
public class Test08 {
    public static void main(String[] args) {

        //输入日期
        System.out.print("请输入日期,按照这种格式:2000-01-01:");
        Scanner sc = new Scanner(System.in);
        String str=sc.next();
        //String str="2022-12-09";
        System.out.println("日\t一\t二\t三\t四\t五\t六\t");

        //String->java.sql.Date->Calendar
        Date date = Date.valueOf(str);
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        //获取本月的天数
        int maxDay=cal.getActualMaximum(Calendar.DATE);
        //获取当前日期的日
        int nowDay=cal.get(Calendar.DATE);
        //将日期调整为本月的1号
        cal.set(Calendar.DATE,1);
        //获取本月1号是本周的第几天
        int num = cal.get(Calendar.DAY_OF_WEEK);
        //前面空出来的天数
        int day=num-1;

        //打印前面的空格
        for (int i = 0; i < day; i++) {
            System.out.print("\t");
        }
        //引入计数器
        int count=0;
        //空出来的日子也要放入计数器
        count=count+day;
        for (int i = 1; i <= maxDay; i++) {
            if(i==nowDay){
                System.out.print(i+"*"+"\t");
            }else {
                System.out.print(i+"\t");
            }
            count++;
            if (count%7 == 0){
                System.out.println();
            }
        }
    }
}

10.2.5 LocalDate/LocalTime/LocalDateTime

一、第一批Date,第二批Calendar,第三批LocalDate(没有偏移,值不改变)

package com.liweixiao.test02;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * @author:LiWeixiao
 * @date:2022/12/16
 * @description:
 */
public class Test09 {
    public static void main(String[] args) {
        //1.实例化
        //方法1:now()
        LocalDate localDate = LocalDate.now();
        System.out.println(localDate);
        LocalTime localTime = LocalTime.now();
        System.out.println(localTime);
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);

        //方法2:of()
        LocalDate of1 = LocalDate.of(2010, 5, 6);
        System.out.println(of1);
        LocalTime of2 = LocalTime.of(12, 12, 12);
        System.out.println(of2);
        LocalDateTime of3 = LocalDateTime.of(1981, 1, 1, 14, 15, 36);
        System.out.println(of3);

        //LocalDate,LocalTime用的不如LocalDateTime多
        //一系列常用的get
        System.out.println(localDateTime.getYear());//2022
        System.out.println(localDateTime.getMonth());//DECEMBER
        System.out.println(localDateTime.getMonthValue());//12
        System.out.println(localDateTime.getDayOfMonth());//16
        System.out.println(localDateTime.getDayOfWeek());//FRIDAY
        System.out.println(localDateTime.getHour());//14
        System.out.println(localDateTime.getSecond());//17

        //不是set,是with
        LocalDateTime localDateTime1 = localDateTime.withYear(2020);
        System.out.println(localDateTime);
        localDateTime1 = localDateTime1.withMonth(2).withDayOfMonth(28);
        System.out.println(localDateTime1);

        //提供了加、减的操作
        LocalDateTime localDateTime2 = localDateTime.plusMonths(2);
        System.out.println(localDateTime2);
        localDateTime2 = localDateTime2.minusMonths(5);
        System.out.println(localDateTime2);
    }
}

二、DateTimeFormatter

package com.liweixiao.test02;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;

/**
 * @author:LiWeixiao
 * @date:2022/12/16
 * @description:
 */
public class Test10 {
    public static void main(String[] args) {
        //格式化:DateTimeFormatter
        //方式一:预定义的标准格式,如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
        DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        //df1可以完成localDateTime和String之间的相互转换
        //LocalDateTime转换成String
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        String str = df1.format(localDateTime);
        System.out.println(str);//2022-12-16T16:11:36.563
        //String转换成LocalDateTime
        TemporalAccessor parse = df1.parse("2022-12-16T16:11:36.563");
        System.out.println(parse);//{},ISO resolved to 2022-12-16T16:11:36.563

        //方式二:本地化相关格式,如:ofLocalizedDateTime()
        //参数:FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT
        DateTimeFormatter df2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        //LocalDateTime-->String
        String str2 = df2.format(LocalDateTime.now());
        System.out.println(str2);//2022年12月16日 下午04时21分33秒
        System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(LocalDateTime.now()));//2022-12-16 16:24:20
        System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).format(LocalDateTime.now()));//22-12-16 下午4:24
        //String->LocalDateTime
        TemporalAccessor parse1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).parse("22-12-16 下午4:24");
        System.out.println(parse1);//{},ISO resolved to 2022-12-16T16:24

        //方式三:自定义的格式,如:ofPattern("yyyy-MM-dd HH:mm:ss"),重点,以后常用
        DateTimeFormatter df3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //LocalDateTime->String
        String str3 = df3.format(LocalDateTime.now());
        System.out.println(str3);//2022-12-16 16:49:50
        //String->LocalDateTime
        TemporalAccessor parse2 = df3.parse("2022-12-16 16:49:50");
        System.out.println(parse2);//{},ISO resolved to 2022-12-16T16:50:42
    }
}

10.3 Math类

java.lang,直接使用,无需导包
所有的方法、常量都被static修饰,类名.直接调用

package com.liweixiao.test023;

/**
 * @author:LiWeixiao
 * @date:2022/12/19
 * @description:
 */
public class Test01 {
    public static void main(String[] args) {
        //常用属性
        System.out.println(Math.PI);
        //常用方法
        System.out.println("随机数:"+Math.random());//[0.0,1.0)
        System.out.println("绝对值:"+Math.abs(-80));
        System.out.println(Math.ceil(9.1));//向上取值
        System.out.println(Math.floor(9.9));//向下取值
        System.out.println(Math.round(3.3));//四舍五入
        System.out.println(Math.round(3.5));
        System.out.println(Math.max(3, 6));//取大值
        System.out.println(Math.min(3, 6));//取小值
    }
}

10.4 Random类

package com.liweixiao.test023;

import java.util.Random;

/**
 * @author:LiWeixiao
 * @date:2022/12/19
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        //Math.random调用的是Random类
        System.out.println(Math.random());

        //学习Random类
        //带参构造器
        Random r1 = new Random(System.currentTimeMillis());
        System.out.println(r1.nextInt());

        //空参构造器
        Random r2 = new Random();
        System.out.println(r2.nextInt(10));//[0,10)
        System.out.println(r2.nextDouble());//[0.0,1.0)
    }
}

10.5 String类

java.lang,直接使用,无需导包
字符串是不可变的
String底层是一个char类型的数组

10.5.1 常用方法

package com.liweixiao.test04;

/**
 * @author:LiWeixiao
 * @date:2022/12/20
 * @description:
 */
public class Test01 {
    public static void main(String[] args) {
        //声明变量,类型为String类型
        String str1 = "abc";
        System.out.println(str1);

        //通过构造器来创建对象
        String str2 = new String();//空构造器
        str2="def";
        System.out.println(str2);
        System.out.println(new String("hij"));//字符串参数构造器
        System.out.println(new String(new char[]{'a', 'b', 'c', 'd'}));//字符数组构造器

        String str4="abc";
        System.out.println(str4.length());
        String str5="";
        System.out.println(str5.isEmpty());
        System.out.println(str4.charAt(1));//获取下标字符,索引从0开始

        String str6=new String("abc");
        String str7=new String("abc");
        System.out.println(str6.equals(str7));//返回true或false,比较值不是比较对象
        System.out.println(str6.compareTo(str7));//返回数字

        String str10="abcdefghijk";
        System.out.println(str10.substring(3));//截取字符串
        System.out.println(str10.substring(3, 6));//截取字符串
        System.out.println(str10.concat("ppp"));//连接字符串

        String str11="abcdeabc";
        System.out.println(str11.replace('a', 'o'));//替换字符串

        String str12="a-b-c-d-e";
        String[] strs = str12.split("-");//分割字符串
        System.out.println(strs);
        System.out.println(Arrays.toString(strs));

        String str13="aBc";
        System.out.println(str13.toUpperCase());//转大写
        System.out.println(str13.toLowerCase());//转小写

        String str14=" a b  c  ";
        System.out.println(str14.trim());
    }
}

以上图片来自网络

以上图片来自网络

常用方法:
length、isEmpty、charAt、equals、compareTo、substring、concat、replace、split、toUpperCase、toLowerCase、trim

10.5.2 内存分析

1.字符串拼接,开辟1个空间,常量池的字符串唯一
2.new关键字创建对象,开辟2个空间

package com.liweixiao.test04;

/**
 * @author:LiWeixiao
 * @date:2022/12/20
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        //字符串拼接
        String s1="a"+"b"+"c";
        String s2="ab"+"c";
        String s3="a"+"bc";
        String s4="abc";
        String s5="abc"+"";
        System.out.println(s1 == s2);//true
        System.out.println(s4 == s5);//true

        //new关键字创建对象
        String s6 = new String("abc");
        System.out.println(s6 == s1);//false
        System.out.println(s6.equals(s1));//true
    }
}

3.有变量参与的字符串拼接
StringBuilder.append()方法

package com.liweixiao.test04;

/**
 * @author:LiWeixiao
 * @date:2022/12/20
 * @description:
 */
public class Test03 {
    public static void main(String[] args) {
        String a="abc";
        String b=a+"def";//StringBuilder.append()
        System.out.println(b);
    }
}

10.6 StringBuilder类

字符串的分类:不可变String,可变字符串StringBuilder、StringBuffer

10.6.1 StringBuilder

StringBuilder底层2个重要的属性:value、count

package com.liweixiao.test05;

/**
 * @author:LiWeixiao
 * @date:2022/12/20
 * @description:
 */
public class Test01 {
    public static void main(String[] args) {
        //创建StringBuilder的对象
        //表面上调用StringBuilder的空构造器,实际底层是对value数组进行初始化,长度16
        StringBuilder sb1 = new StringBuilder();
        System.out.println(sb1.length());//0
        //有参构造器,长度为int
        StringBuilder sb2 = new StringBuilder(3);
        System.out.println(sb2.length());//0
        //有参构造器,长度+16
        StringBuilder sb = new StringBuilder("abc");
        System.out.println(sb.length());//3
        sb.append("def");
        System.out.println(sb.append("aaaaaaaa").append("bbb").append("ccccc").length());//22
    }
}

数组的扩容

private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int newCapacity = (value.length << 1) + 2;
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
        ? hugeCapacity(minCapacity)
        : newCapacity;
}

常用方法:append、delete、insert、replace、setCharAt、substring
可变vs不可变

package com.liweixiao.test05;

/**
 * @author:LiWeixiao
 * @date:2022/12/21
 * @description:
 */
public class Test02 {
    public static void main(String[] args) {
        StringBuilder sb=new StringBuilder();
        System.out.println(sb.append("abc") == sb.append("def"));//true
        String str=new String();
        System.out.println((str = "abc") == (str = "abcd"));//false
    }
}

10.6.2 StringBuffer

StringBuffer与StringBuilder相同,都继承AbstractStringBuilder
StringBuffer从JDK1.0开始,效率低,线程安全
StringBuilder从JDK1.5开始,效率高,线程不安全

posted @ 2022-10-28 14:22  LiWeixiao  阅读(19)  评论(0编辑  收藏  举报