十三、常用类(完结)

十三、常用类

13.1 包装类

13.1.1 包装类的分类

介绍:针对八种基本数据类型对应的引用类型
作用:可以调用包装类里面的方法
分类:

十三、常用类(完结)

13.1.2 包装类的继承关系

  • 学一个类首先要搞清楚类的继承关系
  • Boolean 和 Character 父类一致

十三、常用类(完结)十三、常用类(完结)
  • 其他六种包装类父类一致

十三、常用类(完结)

13.1.3 装箱(boxing)和拆箱(unboxing)

  • jdk5 前手动装箱和拆箱,装箱:基本类型 -> 包装类型,反之,拆箱
  • jdk5 及以后有自动装箱和拆箱方式
  • 自动装箱底层调用的是 valueOf 方法,比如 Integer.valueOf
  • 其它包装类的用法类似,不一一举例
public class Integer01 {
    public static void main(String[] args) {
        //演示包装类和基本数据类型的相互转换,这里以int和Integer演示。
        //1)jdk5前的手动装箱和拆箱方式,装箱:基本类型->包装类型,反之,拆箱
        //手动装箱
        int num1 = 10;
        Integer integer = new Integer(num1); //方式一
        Integer integer1 = Integer.valueOf(num1); //方式二

        //手动拆箱
        int i = integer1.intValue();

        //2)jdk5 以后(含jdk5)的自动装箱和拆箱方式
        //3)自动装箱底层调用的是 valueOf 方法,比如 Integer.valueOf
        Integer integer2  = 33;
        int num2 = integer2;

        //4)其它包装类的用法类似,不一一举例
        Double d = 3.3;
        double d2 = d;

    }
}

13.1.4 包装类 和 String 的相互转换

IntegerString 为例:

public class IntegerVSString {
    public static void main(String[] args) {
        //通过 Integer 和 String 的转换演示包装类与 String 类型的转换
        //Integer -> String
        Integer num1 = 33;
        //方式一、
        String str1 = num1 + "";
        //str1 = 33 + ""; //以前的 int -> String类型, 自动装箱?

        //方式二、
        String str2 = num1.toString();
        //方式三
        String str3 = String.valueOf(num1); //底层也是 toString()
        //str3 = new String(num1); //String 没有这种构造方法

        //String 转 Integer
        String str = "1233";
        //方式一
        Integer integer = Integer.parseInt(str); // parseInt() 返回的 int 类型,这里有自动装箱
        //方式二
        Integer integer1 = Integer.valueOf(str); //手动装箱
        Integer integer2 = new Integer(str); // 手动装箱
    }
}

13.1.5 Integer 和 Character 的常用方法

public class WrapperMethod {
    public static void main(String[] args) {
        //Integer 和 Character 的常用方法
        System.out.println("Integer.MAX_VALUE = " + Integer.MAX_VALUE); //最大范围
        System.out.println("Integer.MIN_VALUE = " + Integer.MIN_VALUE); //最小范围

        System.out.println("Character.digit('1') = " + Character.isDigit('1')); //是不是数字
        System.out.println("Character.isLetter('a') = " + Character.isLetter('a')); //是不是字母
        System.out.println("Character.isUpperCase('A') = " + Character.isUpperCase('A')); //是不是大写
        System.out.println("Character.isLowerCase('a') = " + Character.isLowerCase('a')); //是不是小写
        System.out.println("Character.isSpace(' ') = " + Character.isWhitespace(' ')); //是不是空格

        System.out.println("Character.toUpperCase('a') = " + Character.toUpperCase('a')); //转换成大写
        System.out.println("Character.toLowerCase('A') = " + Character.toLowerCase('A')); //转换成小写
    }
}
  • 更多方法可以查看继承关系图

十三、常用类(完结)

13.1.6 Integer 创建机制

  • 自动装箱底层会调用 valueOf() 方法,只有当参数不在 [-128,127] 区间内,才会返回新的对象,否则返回的是 IntegerCache 属性里与参数的值一致的对象
public class WrapperExercise01 {
    public static void main(String[] args) {
        Integer i1 = new Integer(1);
        Integer i2= new Integer(1);
        System.out.println(i1 == i2); //F 手动创建了对象,这里两个对象地址值不同

        //这里自动装箱,底层调用的 valueOf()
        //查看源码
        /*public static Integer valueOf(int i) {
            if (i >= Integer.IntegerCache.low && i

13.2 String 类

13.2.1 String 类的理解和创建对象

对象:

  • String 对象用于保存字符串,也就是一组字符序列
  • 字符串常量对象是双引号括起的字符序列,如 “hello” ,”world”
  • 字符串的字符使用 Unicode 字符编码,一个字符不区分字母还是汉字占两个字节

类介绍:

  • String 类有很多构造器,构造器的重载
  • String 类有很多构造器,构造器的重载,常用的有(更多的见文档):
  • String s1 = new String();
  • String s2 = new String(String original);
  • String s3 = new String(char[] a);
  • String s4 = new String(char[] a,int startIndex,int count)
  • String s5 = new String(byte[] b)
  • String 类实现了接口 SerializableString 可以串行化:可以在网络传输);接口 Comparable (String 对象可以比较大小)
  • Stringfinal 类,不能被其他的类继承
  • String 有属性 private final char value[]; 用于存放字符串内容
  • 一定要注意: value 是一个 final 类型,且是一个数组,所以 value 存的地址值不可以修改
    即 : value 不能指向新的地址,但是单个字符内容是可以变化
public class String01 {

    public static void main(String[] args) {
        // 1. String 对象用于保存字符串,也就是一组字符序列
        // 2. 字符串常量对象是双引号括起的字符序列,如 "hello" ,"world"
        // 3. 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节
        // 4. String 类有很多构造器,构造器的重载
        //  常用的有(更多的见文档)
        //         String s1 = new String();
        //         String s2 = new String(String original);
        //         String s3 = new String(char[] a);
        //         String s4 = new String(char[] a,int startIndex,int count)
        //         String s5 = new String(byte[] b)
        // 5. String 类实现了接口 Serializable【String 可以串行化:可以在网络传输】
        //                   接口 Comparable [String 对象可以比较大小]
        // 6. String 是 final 类,不能被其他的类继承
        // 7. String 有属性 private final char value[]; 用于存放字符串内容
        // 8. 一定要注意:value 是一个 final 类型,且是一个数组,所以 value 存的地址值不可以修改
        // 即 value 不能指向新的地址,但是单个字符内容是可以变化

        // 1.String 对象用于保存字符串,也就是一组字符序列
        // 看源码可知,字符串 value 是以 char 类型数组保存的
        ///** The value is used for character storage. */
        //private final char value[];

        String str1 = "hello";
        str1 = new String("world");

        // 8. 一定要注意:value 是一个 final 类型,且是一个数组,所以 value 存的地址值不可以修改
        // 即 value 不能指向新的地址,但是单个字符内容是可以变化
        final char value[] = {'h', 'e', 'l', 'l', 'o'};
        value[0] = 'y'; //改里面存的值可以
        //value = new char[2]; //将 value 引用指向新的 char 数组,不可用

    }
}

13.2.2 String 类创建对象机制

两种创建对象方式:

  • 直接赋值 String str = "hello"
  • 用构造器 String str2 = new String("hello")

13.2.3 两种创建对象方式区别

  • 方式一:先在常量池找有没有 "hello" 字符串
  • 如果有则直接传递地址值给引用
  • 没找到则会创建一个,再把地址值传递给引用
  • 方式二:先在堆中创建一个 String 类型的对象,再对 value 属性进行初始化,然后在常量池里找 "hello" 字符串
  • 如果找到了,直接把地址值传递给 value ,然后把堆空间的对象地址值传递给引用
  • 如果没找到,则在常量池创建一个字符串,再进行地址值传递,最后传递给引用的都是堆空间的对象地址值

13.2.4 内存图分析

十三、常用类(完结)

13.2.4 inner() 方法

作用:

  • 返回的是常量池中与该 String 对象内容相同(通过 equals(Object o) 比较)的字符串的地址
  • 如果常量池中没找到对应字符串,就会将字符串存进常量池,再返回该地址值
public class String02 {
    public static void main(String[] args) {
        String a = "hsp";
        String b = new String("hsp");
        System.out.println(a.equals(b)); //T 内容一致
        System.out.println(a == b); //F 地址不一样

        //intern() 源码
        /*@return  a string that has the same contents as this string, but is
         *          guaranteed to be from a pool of unique strings.*/
        //1.返回的是常量池中与该 String 对象内容相同(通过equals(Object o)比较)的字符串的地址
        System.out.println(a == b.intern()); //T
        System.out.println(b == b.intern()); //F 地址值不一样,一个是堆空间的,一个是常量池的

        //2.如果常量池中没找到对应字符串,就会将字符串存进常量池,再返回该地址值
        System.out.println("abc".intern().hashCode()); //96354
        String c = "abc";
        System.out.println(c.hashCode()); //96354
    }
}

13.2.5 练习

十三、常用类(完结)
十三、常用类(完结)

13.2.6 字符串的特性

  • String 是一个 final 类,代表不可变的字符序列
  • 字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的

13.2.7 字符串拼接

  • 两个字符串常量拼接:先判断字符串常量是否有引用指向,没有就创建拼接后的对象
  • 两个字符串引用拼接:底层是创建了 StringBuilder 对象再调用 append(str) 拼接,再调用 toString() 创建拼接后的对象
  • 规则:字符串常量拼接看池,字符串引用拼接看堆

学习思路:一定要看源码

public class StringProperty01 {
    public static void main(String[] args) {
        //1. 两个字符串常量拼接
        //分析:底层做了优化,先判断字符串常量是否有引用指向,"hello" "world" 两个字符串常量没有引用指向,
        //      所以直接创建"helloworld" 常量
        String str1 = "hello" + "world";

        //2. 两个字符串引用拼接
        //Debug查看步骤:
        // 1.创建一个 StringBuilder 对象,初始容量16个字符
        // 2.调用 StringBuilder 的 append("hello"),返回一个 StringBuilder
        // 3.调用 StringBuilder 的 append("carl"),返回一个 StringBuilder
        // 4.调用 StringBuilder 的 toString(),返回一个 new String(value, 0, count) 对象
        // 5.再把 "hellocarl" 的字符串对象传递给 str4 引用
        //总结:底层是:StringBuilder strs = new StringBuilder(), strs.append("hello"), strs.append("carl")
        //      strs 是在堆中,并且 append 是在原来的字符串基础上追加的
        // 规则:字符串常量拼接看池,字符串引用拼接看堆
        String str2 = "hello";
        String str3 = "carl";
        String str4 = str2 + str3;
    }
}

13.2.8 Debug 进入源码设置

十三、常用类(完结)

13.2.9 字符串拼接面试题

  • 字符串常量和字符串引用拼接
public class StringPropertyExercise01 {
    String str = new String("hsp");
    final char[] ch = {'j', 'a', 'v', 'a'};

    public void change(String str, char ch[]) {
        str = "java"; //修改局部变量 str 的引用,指向常量池的 "java"
        ch[0] = 'h';
    }

    public static void main(String[] args) {
        StringPropertyExercise01 ex = new StringPropertyExercise01();
        ex.change(ex.str, ex.ch);
        //Debug步骤:
        // 1. String strs = new StringBuilder()
        // 2. strs.append("hsp")
        // 3. strs.append("and")
        // 4. strs.toString() 返回 new String(value, 0, count)
        // 总结:字符串引用和字符串拼接也是用通过 StringBuilder
        System.out.print(ex.str + "and"); //ex.str 是属性  结果 hspandhava
        System.out.println(ex.ch);
    }
}

13.2.10 String 类常用方法

  • equals() 区分大小写,判断内容是否相等
  • equalsIgnoreCase() 忽略大小写的判断内容是否相等
  • length() 获取字符的个数,字符串的长度
  • indexOf() 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
  • lastIndexOf() 获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
  • substring() 截取指定范围的字符串
  • trim() 去前后空格
  • charAt() 获取某索引处的字符,注意不能使用 Str[index] 这种方式
public class StringMethod01 {
    public static void main(String[] args) {
        String str1 = " hello ";
        String str2 = " HeLLo ";
        //● equals() 区分大小写,判断内容是否相等
        System.out.println("str1.equals(str2) = " + str1.equals(str2)); //false

        //● equalsIgnoreCase() 忽略大小写的判断内容是否相等
        System.out.println("str1.equalsIgnoreCase(str2) = " + str1.equalsIgnoreCase(str2)); //true

        //● length() 获取字符的个数,字符串的长度
        System.out.println("str1.length() = " + str1.length()); //5

        //● indexOf() 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
        System.out.println("str1.indexOf('l') = " + str1.indexOf('l')); //2

        //● lastIndexOf() 获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
        System.out.println("str1.lastIndexOf('l') = " + str1.lastIndexOf('l')); //3

        //● substring() 截取指定范围的字符串 含头不含尾
        System.out.println("str1.substring(0, 4) = " + str1.substring(0, 4)); //hell

        //● trim() 去前后空格
        System.out.println("str1.trim() = " + str1.trim()); //hello

        //● charAt() 获取某索引处的字符,注意不能使用Str[index]这种方式
        System.out.println("str1.charAt(1) = " + str1.charAt(2)); //e
    }
}
  • toUpperCase() 转大写
  • toLowerCase() 转小写
  • concat() 在后面拼接字符串
  • replace() 替换字符串中的字符
  • split() 分割字符串,对于某些分割字符,我们需要转义比如 | \\
  • 案例: String poem= "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦”; 和 文件路径
  • compareTo() 比较两个字符串的大小 前者大则返回正数,后者大返回负数,相同返回0
  • toCharArray() 转换成字符数组
  • format() 格式字符串,按顺序替换指定字符串里的占位符,用对应格式变量
  • %s 字符串
  • %c 字符
  • %d 整型
  • %.2f 浮点型 保留两位小数
  • 案例,将一个人的信息格式化输出
public class StringMethod02 {
    public static void main(String[] args) {
        String str1 = "Hello";
        //● toUpperCase() 转大写
        System.out.println("str1.toUpperCase() = " + str1.toUpperCase()); //HELLO

        //● toLowerCase() 转小写
        System.out.println("str1.toLowerCase() = " + str1.toLowerCase()); //hello

        //● concat() 在后面拼接字符串
        System.out.println("str1.concat(\",World\") = " + str1.concat(",World")); //Hello,World

        //● replace() 替换字符串中的字符
        System.out.println("str1.replace('e', 'a') = " +
                str1.replace('e', 'a')); //Hallo

        //● split() 分割字符串,对于某些分割字符,我们需要转义比如 | \\ 等
        //  ○ 案例:String poem= "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        String[] strings = poem.split(",");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }

        //  和 文件路径.

        poem = "E:\\aaa\\bbb";
        String[] strings1 = poem.split("\\\\");
        for (int i = 0; i < strings1.length; i++) {
            System.out.println(strings1[i]);
        }

        //● compareTo() 比较两个字符串的大小 前者大则返回正数,后者大返回负数,相同返回0
        // 分析:(1) 如果长度相同,并且每个字符也相同,就返回 0
        //      (2) 如果在进行比较时,可以区分字母大小或大小写就返回:
        //          if (c1 != c2) {
        //              return c1 - c2;
        //          }
        //      (3) 如果前面的部分都相同,就返回 str1.len - str2.len
        String str2 = "hello,world";
        System.out.println("str1.length() = " + str1.length()); //5
        System.out.println("str2.length() = " + str2.length()); //11
        System.out.println("str1.compareTo(str2) = " + str1.compareTo(str2)); //-32

        //● toCharArray() 转换成字符数组
        char[] chars = str1.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.println("chars[i] = " + chars[i]);
        }

        //● format() 格式字符串 按顺序替换指定字符串里的占位符,用对应格式变量
        //  ○ %s 字符串
        //  ○ %c 字符
        //  ○ %d 整型
        //  ○ %.2f 浮点型 保留两位小数
        //● 案例,将一个人的信息格式化输出
        String name = "john";
        int age = 10;
        double score = 56.857;
        char gender = '男';
        //将所有的信息都拼接在一个字符串
        String info = "我的信息是:姓名 %s, 年龄 %d, 分数 %.1f, 性别 %c";
        //我的信息是:姓名 john, 年龄 10, 分数 56.9, 性别 男
        System.out.println(String.format(info, name, age, score, gender));
    }
}

13.3 StringBuffer 类

13.3.1 StringBuffer 类介绍

  • java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删。
  • 很多方法与 String 相同,但 StringBuffer 是可变长度的。
  • StringBuffer 是一个容器。

StringBuffer 类继承关系

十三、常用类(完结)
十三、常用类(完结)
public class StringBuffer01 {
    public static void main(String[] args) {
        //1. StringBuffer 的直接父类 是 AbstractStringBuilder
        //2. StringBuffer 实现了 Serializable, 即 StringBuffer 的对象可以串行化
        //3. 在父类中 AbstractStringBuilder 有属性 char[] value,不是 final
        //   该 value 数组存放 字符串内容,因此存放在堆中的
        //4. StringBuffer 是一个 final 类,不能被继承
        //5. 因为 StringBuffer 字符内容是存在 char[] value, 所以变化(增加/删除)
        //   不用每次都更换地址(即不是每次创建新对象), 所以效率高于 String
        StringBuffer stringBuffer = new StringBuffer();
    }
}

13.3.2 StringBuffer 和 String 的区别

  • 内容:
  • String 保存的是字符串 常量
  • StringBuffer 保存的是字符串 变量
  • 是否可修改
  • String 里面的值 不能更改,每次 String 类的更新实际上就是更改 String 对象引用的地址,效率较低 private final char value[]
  • StringBuffer 里面的值 可以更改,有一个缓存机制,每次 StringBuffer 的更新实际上可以更新内容,不用每次更新地址,效率较高 char[]value; 放在堆。

13.3.3 StringBuffer 和 String 相互转换

public class StringVSStringBuffer {
    public static void main(String[] args) {
        String str = "石头人";

        //String -> StringBuffer
        //方式一:构造器
        StringBuffer stringBuffer = new StringBuffer(str);
        //方式二:append() 在后面添加字符串,返回 StringBuffer 对象
        StringBuffer stringBuffer1 = new StringBuffer();
        StringBuffer hello = stringBuffer1.append("hello");
        System.out.println(hello); //石头人hello

        //StringBuffer -> String
        //方式一:StringBuffer的toString
        String s = stringBuffer.toString();
        //方式二:String构造器
        String s1 = new String(hello);
    }
}

13.3.4 StringBuffer 类常用方法

package com.hspedu.stringbuffer_;

/**
 * @author: Carl Zhang
 * @create: 2021-11-29 16:17
 */
public class StringBufferMethod {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("hello,world");
        //增 直接修改的堆空间的内容
        stringBuffer.append(",张三丰");
        System.out.println("stringBuffer = " + stringBuffer); //stringBuffer = hello,world,张三丰
        System.out.println(stringBuffer.append(true).append(3)); //hello,world,张三丰true3
        StringBuffer sb = new StringBuffer();
        sb.append(null); //底层AbstractStringBuilder调用的appendNull()

        //删 删除范围内的字符,含头不含尾
        stringBuffer.delete(0, 5);
        System.out.println("stringBuffer = " + stringBuffer); //,world,张三丰true3
        //stringBuffer.delete(16, 17); //end > count
        System.out.println("stringBuffer = " + stringBuffer); //异常StringIndexOutOfBoundsException

        //改 用指定字符串替换范围内的字符,含头不含尾
        stringBuffer.replace(0, 6, "hello");
        System.out.println("stringBuffer = " + stringBuffer); //hello,张三丰true3

        //查 查找指定的字符串串在字符串第一次出现的索引,如果找不到返回-1
        System.out.println(stringBuffer.indexOf("hello")); //0

        //插 在指定位置插入值,原来位置的字符串往后移
        stringBuffer.insert(9, ',');
        System.out.println("stringBuffer = " + stringBuffer); //hello,张三丰,true3
        stringBuffer.insert(6, "world,");
        System.out.println("stringBuffer = " + stringBuffer); //hello,world,张三丰,true3

        //长度
        System.out.println("stringBuffer.length() = " + stringBuffer.length()); //21
    }
}

13.3.5 练习

package com.hspedu.stringbuffer_;

import java.util.Scanner;

/**
 * @author: Carl Zhang
 * @create: 2021-11-29 16:57
 */
public class StringBufferExercise02 {
    public static void main(String[] args) {
        /*
         * 输入商品名称和商品价格,要求打印效果示例, 使用前面学习的方法完成:
         * 商品名 商品价格
         * 手机 123,564.59 //比如 价格 3,456,789.88
         * 要求:价格的小数点前面每三位用逗号隔开, 在输出。
         * */
        //思路分析:
        //1. 需要定义Scanner
        //2. 用 String 变量保存用户输入的 name, price
        //3. 需要用到StringBuffer的方法,将 price 转成 StringBuffer
        //3. 从小数点的位置前三位起,倒序遍历 price 字符串
        //4. 每三位就插入"," insert()
        Scanner scanner = new Scanner(System.in);
        //String price = "3456789.88";
        System.out.print("请输入商品名:");
        String name = scanner.next();
        System.out.print("请输入价格:");
        String price = scanner.next();
        StringBuffer priceBuffer = new StringBuffer(price);
        for (int i = priceBuffer.indexOf(".") - 3; i >= 0; i -= 3) {
            priceBuffer.insert(i, ',');
        }
        //System.out.println("price = " + priceBuffer);
        System.out.println("商品\t价格\n" + name + "\t" + priceBuffer);
    }
}

13.4 StringBuilder 类

13.4.1 StringBuilder 类介绍

  • 一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步,( StringBuilder 不是线程安全)。该类被设计用作 StringBuffer 的一个简易替换, 用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类因为在大多数实现中,它比 StringBuffer 要快[后面测]。
  • StringBuilder 上的主要操作是 append()insert() 方法,可重载这些方法,以接受任意类型的数据。

类继承关系

十三、常用类(完结)
十三、常用类(完结)
十三、常用类(完结)
public class StringBuilder_ {
    public static void main(String[] args) {
        //1.StringBuilder 继承AbstractStringBuilder类
        //2.实现了Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
        //3.StringBuilder 是final类,不能被继承
        //4.StringBuilder 对象字符序列仍然是存放在其父类AbstractStringBuilder的 charl]value;
        //因此,字符序列是堆中
        //5.StringBuilder的方法,没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用
        //StringBuilder

        StringBuilder stringBuilder = new StringBuilder();
    }
}

13.4.2 String、StringBuffer、StringBuilder 比较

  • StringBuilderStringBuffer 非常类似,均代表可变的字符序列,而且方法也一样
  • String :不可变字符序列,效率低,但是 复用率高。
  • StringBuffer :可变字符序列、效率 较高(增删)、 线程安全,看源码
  • StringBuilder :可变字符序列、效率 最高线程不安全
  • String 使用注意说明:
  • string s = "a"; 创建了一个字符串
  • s += "b"; 实际上原来的 "a" 字符串对象已经丢弃了,现在又产生了一个字符串 s + "b"(也就是 "ab" )。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大。影响程序的性能
  • 结论:如果我们对 String 做大量修改,不要使用 String

13.4.3 String、StringBuffer 和 StringBuilder 的效率测试

package com.hspedu.stringbuilder_;

/**
 * @author: Carl Zhang
 * @create: 2021-12-01 10:40
 */
public class StringVsStringBufferVsStringBuilder {
    public static void main(String[] args) {
        long startTime = 0L;
        long endTime = 0L;
        StringBuffer buffer = new StringBuffer("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 80000; i++) { //拼接80000次
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer 的执行时间:" + (endTime - startTime)); //12

        StringBuilder builder = new StringBuilder("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 80000; i++) { //拼接80000次
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder 的执行时间:" + (endTime - startTime)); //5

        String text = "";
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 80000; i++) { //拼接80000次
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String 的执行时间:" + (endTime - startTime)); //4294
    }
}

13.4.4 String、StringBuffer 和 StringBuilder 的选择

使用结论:

  • 如果字符串存在大量的修改操作,一般使用 StringBufferStringBuilder
  • 如果字符串存在大量的修改操作,并在 单线程的情况,使用 StringBuilder (方法同 StringBuffer&#x4E00;&#x81F4;
  • 如果字符串存在大量的修改操作,并在 多线程的情况,使用 StringBuffer
  • 如果我们字符串很少修改,被 多个对象 引用,使用 String,比如配置信息等

13.5 Math 类

13.5.1 Math 类基本介绍

包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

13.5.2 Math 类常用方法

详见 JDK 文档( 不要背!

  • abs 绝对值
  • pow 求幂
  • ceil 向上取整
  • floor 向下取整
  • round 四舍五入
  • sqrt 求开方
  • random 求随机数
  • max 求两个数的最大值
  • min 求两个数的最小值
package com.hspedu.math;

/**
 * @author: Carl Zhang
 * @create: 2021-12-01 11:04
 */
public class Math01 {
    public static void main(String[] args) {
        //1.abs 绝对值
        int abs = Math.abs(-9);
        System.out.println(abs); //9
        //2.ceil 向上取整
        double ceil = Math.ceil(9.4);
        System.out.println(ceil); //10.0
        //3.floor 向下取整
        double floor = Math.floor(8.8);
        System.out.println(floor); //8.0
        //4.round 四舍五入
        long round = Math.round(5.6);
        System.out.println(round); //6
        //5.sqrt 求开方
        double sqrt = Math.sqrt(9);
        System.out.println(sqrt); //3.0
        //6.random 求随机数 返回 0 - 1 的数,含0不含1
        //思考:
        //请写出获取a-b之间的一个随机整数,a,b均为整数?2-7
        int a = 2;
        int b = 7;
        int rand = (int)(a + Math.random() * (b + 1 - a));
        System.out.println(rand); //6
        //7.max 求两个数的最大值
        int max = Math.max(2, 888); //888
        System.out.println(max);
        //8.min 求两个数的最小值
        int min = Math.min(2, -11);
        System.out.println(min); //-11
    }
}

13.6 Arrays 类

13.6.1 Arrays 类常用方法

  • toString() 返回数组的字符串表现形式 + [ ]
  • sort() 自然排序顺序
  • 方法重载:自定义排序规则, sort(arr, new Comparator(){...})
package com.hspedu.arrays_;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author: Carl Zhang
 * @create: 2021-12-01 15:01
 */
public class Array01 {
    public static void main(String[] args) {
        Integer[] nums = {1, 33, 0, 22, 8, 90};

        //1. toString() 返回数组的字符串表现形式 + []
        String s = Arrays.toString(nums);
        System.out.println(s); //[1, 33, 0, 22, 8, 90]

        //2.sort() 自然排序 顺序
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums)); //[0, 1, 8, 22, 33, 90]
        //自定义排序规则
        //看源码:
        //1. 最终调用的是TimSort.sort(a, 0, a.length, c, null, 0, 0);
        //2. 然后到 TimSort 类的 private static  void binarySort(T[] a,
        //                int lo, int hi, int start,Comparator c)
        //3. 根据动态绑定机制,访问传入的匿名内部类的 compare 方法
        //while (left < right) {
        //    int mid = (left + right) >>> 1;
        //    if (c.compare(pivot, a[mid]) < 0) //根据compare方法返回数的正负来决定规则
        //        right = mid;
        //    else
        //        left = mid + 1;
        //}
        //4. 根据 public int compare(Object o1, Object o2) 返回的数的正负来决定排序规则,
        //   体现了接口编程 + 动态绑定 + 匿名内部类的综合使用将来的底层框架和源码的使用方式,会非常常见
        Arrays.sort(nums, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer)o1;
                Integer i2 = (Integer)o2;
                return i2 - i1;
            }
        });
        System.out.println(Arrays.toString(nums)); //[90, 33, 22, 8, 1, 0]
    }
}

模拟自定义排序

package com.hspedu.arrays_;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author: Carl Zhang
 * @create: 2021-12-01 16:25
 */
public class ArraySortCustom {
    public static void main(String[] args) {
        Integer[] nums = {3, 0, -1, 22, -11, 9};

        //调用自定义排序方法
        ArraySort.sortCustom(nums, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2;
                return i2 - i1;
            }
        });

        //打印数组
        System.out.println(Arrays.toString(nums));
    }
}

class ArraySort {
    public static void sortCustom(Integer[] nums, Comparator c) {
        Integer temp = 0;
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - i - 1; j++) {
                //排序规则 根据返回的数的正负来判断
                if (c.compare(nums[j], nums[j + 1]) > 0) {
                    temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
        }
    }
}
  • binarySearch() 通过二叉法在数组内查找某个数, 找到则返回对应下标
  • copyOf() 将指定数组拷贝到指定长度的数组内,返回拷贝后的数组
  • fiil() 用指定值填充指定数组的所有元素,可以理解为替换
  • equals() 比较两个数组是否相等 返回 boolean 值
  • asList() 将数组转换成 List集合 并返回
package com.hspedu.arrays_;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author: Carl Zhang
 * @create: 2021-12-01 16:55
 */
public class ArraysMethod02 {
    public static void main(String[] args) {
        Integer[] nums = {1, 22, 33, 55, 133, 900};
        //binarySearch() 通过二叉法在数组内查找某个数, 找到则返回对应下标
        //找不到则 return -(low + 1);
        //注意:该数组必须是排好正序的
        int index = Arrays.binarySearch(nums, 33);
        System.out.println(index);

        //将数组排倒序
        Arrays.sort(nums, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return (Integer) o2 - (Integer) o1;
            }
        });
        //查找
        index = Arrays.binarySearch(nums, 900);
        //打印
        System.out.println(index); //-7

        //copyOf() 将指定数组拷贝到指定长度的数组内,返回拷贝后的数组
        //1. 如果 newLength 小与原数组,就少拷贝元素
        //2. 如果 newLength 大于原数组,就会给空余的位置默认值
        //3. 如果 newLength < 0,就会抛异常 NegativeArraySizeException
        Integer[] nums2 = Arrays.copyOf(nums, nums.length + 1);
        System.out.println(Arrays.toString(nums2));

        //fiil() 用指定值填充指定数组的所有元素,可以理解为替换
        Integer[] num3 = new Integer[3];
        Arrays.fill(num3, 100);
        System.out.println(Arrays.toString(num3)); //[100, 100, 100]

        //equals() 比较两个数组是否相等 返回 boolean 值
        boolean result = Arrays.equals(nums, nums2);
        System.out.println(result); //false

        //asList() 将数组转换成 List集合 并返回
        //1. List(编译类型) 是接口
        //2. asList 运行类型是 java.util.Arrays$ArrayList
        //   是 Arrays 类的 静态内部类 private static class ArrayList extends AbstractList
        //                              implements RandomAccess, java.io.Serializable
        List asList = Arrays.asList(num3);
        System.out.println("asList = " + asList); //asList = [100, 100, 100]
        System.out.println("asList.getClass() = " + asList.getClass()); //java.util.Arrays$ArrayList
    }
}

13.7 System 类

13.7.1 System 类常用方法

  • exit() :退出当前程序 ,参数 0 表示正常退出
  • arraycopy():复制数组元素,比较适合底层调用,一般使用 Arrays.copyOf() 完成复制数组
  • currentTimeMillis() :返回当前时间距离1970-1-1的毫秒数运行垃圾回收机制
  • System.gc() :运行垃圾回收机制,(见基础语法 8.9.5)
public class System_ {
    public static void main(String[] args) {
        //exit() 退出当前程序 ,参数 0 表示正常退出
        System.out.println("Hello");
        //System.exit(0); //0表示正常退出
        System.out.println("World");

        //arraycopy():复制数组元素,比较适合底层调用,一般使用Arrays.copyOf完成复制数组
        int[]src={1,2,3};
        int[]dest=new int[3];
        //源数组
        //* @param      src      the source array.

        //从源数组的起始坐标开始拷贝
        //* @param      srcPos   starting position in the source array.

        //目标数组
        //* @param      dest     the destination array.

        //目标数组的起始坐标
        //* @param      destPos  starting position in the destination data.

        //要拷贝的元素个数
        //* @param      length   the number of array elements to be copied.

        System.arraycopy(src,0,dest,0,3);
        System.out.println(Arrays.toString(dest)); //[1, 2, 3]

        //currentTimeMillis():返回当前时间距离1970-1-1的毫秒数
        System.out.println(System.currentTimeMillis());

        //System.gc() 运行垃圾回收机制
    }
}

13.8 BigInteger 和 BigDecimal 类

13.8.1 应用场景

  • Biglnteger 适合保存比较大的整型
  • BigDecimal 适合保存精度更高的浮点型(小数)

13.8.2 常用方法

  • add()
  • subtract()
  • multiply()
  • divide()
public class BigInteger_ {
    public static void main(String[] args) {
        //保存大数时用long存不了 Long number too large
        //long l = 999999999999999999999999999l;

        //用BigInteger保存大数
        BigInteger bigInteger = new BigInteger("999999999999999999999999999");
        System.out.println("bigInteger = " + bigInteger);
        BigInteger bigInteger1 = new BigInteger("100000000000000000000000000");
        //add加
        BigInteger add = bigInteger.add(bigInteger1);
        System.out.println("add = " + add);
        //subtract减
        BigInteger subtract = bigInteger.subtract(bigInteger1);
        System.out.println("subtract = " + subtract);
        //multiply乘
        BigInteger multiply = bigInteger.multiply(bigInteger1);
        System.out.println("multiply = " + multiply);
        //divide除
        BigInteger divide = bigInteger.divide(bigInteger1);
        System.out.println("divide = " + divide);
    }
}
public class BigDecimal_ {
    public static void main(String[] args) {
        //保存精度很高的数用double表示不了
        double d = 99.99999999999999999d;
        System.out.println(d); //100.0
        //用BigDecimal
        BigDecimal bigDecimal = new BigDecimal("99.99999999999999999");
        System.out.println(bigDecimal);

        //add() 加,传入BigDecimal对象
        BigDecimal bigDecimal1 = new BigDecimal("0.00000000000000001");
        BigDecimal add = bigDecimal.add(bigDecimal1);
        System.out.println(add);
        //subtract减
        BigDecimal subtract = bigDecimal.subtract(bigDecimal1);
        System.out.println(subtract);
        //multiply乘
        BigDecimal multiply = bigDecimal1.multiply(bigDecimal1);
        System.out.println(multiply);
        //divide除
        BigDecimal divide = bigDecimal.divide(bigDecimal1);
        System.out.println(divide);
    }
}

13.9 日期类

13.9.1 第一代日期类 Date

介绍:

  • Date 类,获取当前日期对象,精确到毫秒
  • SimpleDateFormat 类,对日期进行格式化和解析
  • 格式化:日期 -> 文本 format()
  • 解析:文本 -> 日期 parse()

常用方法及案例:

public class Date01 {
    public static void main(String[] args) throws ParseException {
        //第一代日期类 Date
        //1. 获取当前系统时间
        // 默认格式是外国格式,可以通过 SimpleDateFormat 进行格式化
        Date date = new Date();
        System.out.println(date); //Thu Dec 02 11:25:28 CST 2021
        //* 通过毫秒数(long类型)获取日期
        Date date1 = new Date(1638416256789l);
        System.out.println(date1); //Thu Dec 02 11:32:44 CST 2021

        //2. 将Date格式化成String
        //  * 构造器后面可填的字母见 JDK
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
        String s = simpleDateFormat.format(date);
        System.out.println("当前时间:" + s);

        //3.将文本转换成 Date类型
        //  * 转换后的文本格式为Date的默认格式
        //  * 可通过format方法再次格式化
        //  * 注意:要转换的文本必须和simpleDateFormat的格式一致,否则会抛异常ParseException
        String time = "2021-12-02 11:32:44 星期四";
        Date parse = simpleDateFormat.parse(time);
        System.out.println(parse); //Thu Dec 02 11:32:44 CST 2021
    }
}

13.9.2 第二代日期类 Calendar

  • 类声明public abstract class Calendar implements Serializable, Cloneable, Comparable<calendar></calendar>
  • Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEARMONTHDAY_OF_MONTHHOUR日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法。
  • 例:获取年份 int i = calendar.get(Calendar._YEAR_);

13.9.3 第三代日期类 LocalDateTime

前几代日期类的不足:

  • JDK 1.0 中包含了一个 java.util.Date 类,但是它的大多数方法已经在 JDK 1.1 引入 Calendar 类之后被弃用了。
  • Calendar也存在问题是:
  • 可变性:像日期和时间这样的类应该是不可变的。
  • 偏移性: Date 中的年份是从1900开始的,而月份都从0开始。
  • 格式化:格式化只对 Date 有用, Calendar 则不行。
  • 此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s

JDK8 引入了新的日期类 LocalDateTime
LocalDateTime 介绍:

  • LocalDate 只包含日期,可以获取年、月、日字段
  • LocalTime 只包含时间,可以获取时、分、秒字段
  • LocalDateTime 包含日期+时间,可以获取日期和时间字段

DateTimeFormatter 类:类似于 SimpleDateFormat 可对日期进行格式化

public class LocalDateTime_ {
    public static void main(String[] args) {
        //1. 使用 now() 返回表示当前日期时间的对象
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime); //2021-12-02T14:19:41.629

        //2. 使用 DateTimeFormatter 格式化LocalDateTime对象
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String time = dateTimeFormatter.format(localDateTime);
        System.out.println(time); //2021-12-02 14:23:21

        //获取其他时间字段
        System.out.println("年:" + localDateTime.getYear());
        System.out.println("月:" + localDateTime.getMonth());
        System.out.println("月:" + localDateTime.getMonthValue());
        System.out.println("日:" + localDateTime.getDayOfMonth());
        System.out.println("时:" + localDateTime.getHour());
        System.out.println("分:" + localDateTime.getMinute());
        System.out.println("秒:" + localDateTime.getSecond());

        //提供 plus 和 minus 方法可以对当前时间进行加或者减
        //看看 890 天后,是什么时候 把 年月日-时分秒
        LocalDateTime plusDays = localDateTime.plusDays(890);
        String format = dateTimeFormatter.format(plusDays);
        System.out.println("890 天后是" + format);

        //看看在 3456 分钟前是什么时候,把 年月日-时分秒输出
        LocalDateTime localDateTime1 = localDateTime.minusMinutes(3456);
        String format1 = dateTimeFormatter.format(localDateTime1);
        System.out.println("3456 分钟前是" + format1);
    }
}

更多方法查看JDK文档

public class LocalDateTime02 {
    public static void main(String[] args) {
        //MonthDay类:检查重复时间
        //是否是闰年
        //增加日期的某个部分
        //使用plus方法测试增加时间的某个部分
        //使用minus方法测试查看一年前和一年后的日期
        MonthDay now = MonthDay.now();
        System.out.println(now); //--12-02
        MonthDay now1 = MonthDay.now();
        System.out.println(now.equals(now1));

        //是否是闰年
        LocalDateTime ldt = LocalDateTime.now();
        boolean leapYear = ldt.toLocalDate().isLeapYear();
        System.out.println(leapYear); //false
    }
}

13.9.4 Instant 时间戳

  • 类似于 Date
  • 提供了一系列和 Date 类转换的方式
  • Instant &#x2014;> DateDate date=Date.from(instant);
  • Date &#x2014;> InstantInstant instant=date.tolnstant();
public class Instant_ {
    public static void main(String[] args) {
        //1.通过 静态方法 now() 获取表示当前时间戳的对象
        Instant now = Instant.now();
        System.out.println(now); //2021-12-02T06:30:48.638Z

        //2. 通过 from 可以把 Instant 转成 Date
        Date from1 = Date.from(now);
        System.out.println("from1 = " + from1); //Thu Dec 02 14:33:00 CST 2021

        //3. 通过 toInstant() 将 date 转换成 Instant
        Date date = new Date();
        Instant instant = date.toInstant();
        System.out.println("instant = " + instant); //2021-12-02T06:36:59.433Z
    }
}

Original: https://www.cnblogs.com/Carl-Zhang/p/15763050.html
Author: Carl-Zhang
Title: 十三、常用类(完结)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/572498/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Guava Retryer实现接口重试

    前言 小黑在开发中遇到个问题,我负责的模块需要调用某个三方服务接口查询信息,查询结果直接影响后续业务逻辑的处理; 这个接口偶尔会因网络问题出现超时,导致我的业务逻辑无法继续处理; …

    Java 2023年6月7日
    085
  • mybatis-plus详解

    旧的代码生成 记得导包,依赖如下 com.baomidou mybatis-plus-boot-starter 3.5.1 com.baomidou mybatis-plus-ge…

    Java 2023年6月16日
    076
  • java基础之运算符的优先级

    运算符的优先级(从高到低) 优先 描述 运算符 1 括号 ()、[] 2 正负号 +、- 3 自增自减,非 ++、–、! 4 乘除,取余 、/、%* 5 加减 +、- …

    Java 2023年6月6日
    069
  • spring-boot 使用 spring-boot-starter-mail 发送邮件

    参考文档 https://docs.spring.io/spring-framework/docs/5.3.10/reference/html/integration.html#m…

    Java 2023年5月30日
    087
  • Hyperledger Fabric 核心概念

    一、说明 区块链是一个透明的,基于不可变模式的去中心化系统,核心就是一个分布式账本,记录网络上发生的所有交易。 区块链网络主要有三种类型:公共区块链、联盟区块链,以及私有区块链;我…

    Java 2023年6月6日
    0111
  • 数据库篇:mysql锁详解

    前言 sql事务的执行,如果需要锁定数据进行更新操作,则必定离不开锁 共享锁和排他锁 表锁 行锁 Record Lock 间隙锁 Gap Lock 行锁+间隙锁 Next-Key …

    Java 2023年6月5日
    088
  • 技术人的成长

    摘要 最近和朋友,同事交流了一些关于技术人如何成长的话题。为什么聊到这个话题,因为程序员这个职业发展真的很快,2、3年的时间,相同起点的人可能就会被拉开很大差距,所以技术人一定要持…

    Java 2023年6月8日
    0104
  • 自定义MyBatis

    一. 原生 JDBC 1. 原生JDBC使用 public static void main(String[] args) { Connection conn = null; Pr…

    Java 2023年6月5日
    094
  • javaweb学生管理系统 第一次总结

    JavaWeb 学生管理系统 第一次总结 ; 具备的知识 java se 高级数据库jsselvetEl表达式jsp 项目 目录结构 [外链图片转存失败(img-dfQq8aOt-…

    Java 2023年6月8日
    092
  • Mybatis完整版详解

    一、简介 1.什么是MyBatis MyBatis 是一款优秀的持久层框架 它支持自定义 SQL、存储过程以及高级映射。 MyBatis 免除了几乎所有的 JDBC 代码以及设置参…

    Java 2023年6月14日
    058
  • CORS与CSRF在Spring Security中的使用

    背景 在项目使用了Spring Security之后,很多接口无法访问了,从浏览器的网络调试窗看到的是CORS的报错和403的报错 分析 我们先来看一下CORS是什么,和它很相似的…

    Java 2023年6月5日
    090
  • Spring Boot:整合MyBatis框架

    综合概述 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBa…

    Java 2023年5月30日
    0105
  • SpringBoot扩展接口-SpringApplicationInitializer 初始化器

    这个扩展接口的主要目的是允许我们对ConfigurableApplicationContext的实例做额外的初始化操作 调用这个接口之前 1、添加自定义事件监听器(非SpringB…

    Java 2023年5月30日
    078
  • 为什么会有996

    从发展阶段来看,国内的互联网公司大多都处于 原始积累阶段,大家都是 &#x4F60;&#x6709;&#x4EC0;&#x4E48;&#x5…

    Java 2023年6月15日
    069
  • 如何使用原生的Feign

    什么是Feign Feign 是由 Netflix 团队开发的一款基于 Java 实现的 HTTP client,借鉴了 Retrofit、 JAXRS-2.0、WebSocket…

    Java 2023年6月14日
    087
  • Vue(十三)—过滤器filter,filters

    官网:https://cn.vuejs.org/v2/api/#filters https://cn.vuejs.org/v2/api/#Vue-filter 分为全局过滤器和局部…

    Java 2023年6月13日
    094
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球