• 【重拾Java系列】—— 八大常用类


    包装类

    • 针对八种基本数据类型相应的引用类型 —— 包装类
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • 包装类和基本数据的转换:

    (1) jdk5之前采用手动装箱和拆箱的方式
    (2) jdk5及以后采用自动装箱和拆箱的方式
    (3)自动装箱底层调用的是valueOf方法
    【装箱:基本数据类型 -> 包装类; 拆箱: 包装类 -> 基本数据类型】

    手动装箱:

    int n = 100;
    Integer integer = new Integer(n);
    Integer integer1 = Integer.valueOf(n);
    
    • 1
    • 2
    • 3

    手动拆箱:

    int n2 = integer.intValue();
    
    • 1

    自动装箱:

    //底层是用Integer.valueOf(parameter)实现的
    Integer integer2 = n;
    
    • 1
    • 2

    自动拆箱

    //底层采用 parameter.intValue();
    int n3 = integer2;
    
    • 1
    • 2

    三元运算符是一个整体,精度要看整体的最高精度

    • 包装类与String转换: 【以Integer为例】
    Integer i = 100;
    //利用toString()方法完成Integer转换成String
    String s1 = i.toString();
    String s2 = String.valueOf(i);
    String s3 = i + "";
    //String转化为Integer
    String str = "123";
    Integer i1 = Integer.paraseInt(str);
    Integer i2 = new Integer(str);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • Integer经典面试题:
    //示例一
    Integer i1 = new Integer(127);
    Integer i2 = new Integer(127);
    System.out.println(i1 == i2);
    //示例二
    Integer i3 = new Integer(128);
    Integer i4 = new Integer(128);
    System.out.println(i3 == i4);
    //示例三
    Integer i5 = 127;
    Integer i6 = 127;
    System.out.println(i5 == i6);
    //示例四
    Integer i7 = 128;
    Integer i8 = 128;
    System.out.println(i7 == i8);
    //示例五
    Integer i9 = 127;
    Integer i10 = new Integer(127);
    System.out.println(i9 == i10);
    //示例六
    Integer i11 = new Integer(127);
    int i12 = 127;
    System.out.println(i11 == i12);
    //示例七
    Integer i13 = 128;
    int i14 = 128;
    System.out.println(i13 == i14);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    输出结果如下:
    在这里插入图片描述
    对产生的结果分析:

    • 通过new来创建新的整型包装类的对象,所以在利用==比较时肯定返回false 【所以示例一、二、五都为 false
    • 示例三、四都是采用的自动装箱,底层是通过Integer.valueOf()方法实现的,通过Ctrl+B快捷键查看源码
        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    当参数大于IntegerCache.low,小于IntegerCache.high时,是直接在缓冲数组中取的值;当不在这个范围时才会创建一个新Integer对象
    进一步查询源码可知:IntegerCache.low为-128, IntegerCache.high为127
    所以示例三中,参数127在范围内,所以两个对象的地址相同,返回true;
    示例四中,参数128不在范围内,所以两个对象的地址不同,返回false。

    • 只要有基本数据类型参与==比较,判断的就是 值是否相同【所以示例六、七返回true】

    String类

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

    一、String类常用构造器

    String s1 = new String();
    String s2 = new String(parameter);
    String s3 = new String(char [] ch);
    String s4 = new String(char [] c, int startIndex, int count);
    
    • 1
    • 2
    • 3
    • 4
    • String类实现了Serializable接口 和 Comparable接口,可以在网络传输,也可以相互比较
    • String 是final类,不能被继承,而且初始化之后就不能改变 【字符可以修改,地址不能修改】
      在这里插入图片描述

    可以修改字符的内容,例如:s = "you";,此时s对应的地址仍然是0x123,只是内容发生了变化

    • String 有属性 private final char value[] 用于存储字符

    二、String对象的创建方式

    String s1 = "study";
    String s2 = new String("study");
    
    • 1
    • 2

    (1)通过构造器创建的对象:现在堆中创建空间,里面维护了value属性,指向常量池的空间,如果常量池有该字符串,则通过value直接指向,否则在常量池中重新创建,最终指向堆中的空间地址
    在这里插入图片描述

    (2)通过直接赋值的对象:先从常量池中查看是否有该字符串的数据空间,如果有直接指向;如果没有则重新创建,然后指向。最终指向的是常量池的空间地址

    堆中存放的是引用对象的地址,如果问对象的属性,那么是在常量池中的地址。

    Person p = new Person();
    p.name = "赵先生";
    
    • 1
    • 2

    此时这个对象p指向的是在堆中引用对象的地址,而p.name是在方法区的常量池中的地址
    对于intern()方法,其作用是获取字符串对象在常量池中的地址

    String s1 = "zbc";
    String s2 = new String("zbc");
    System.out.println(s1 == s2);
    System.out.println(s1 == s2.intern());
    
    • 1
    • 2
    • 3
    • 4

    s1对象直接赋值获得的,s2 对象是通过构造器获得的。所以s1的地址是该字符串在常量池中的地址,s2的地址是该引用对象在堆中的地址
    所以输出的第一个结果为 false
    s2.intern() 返回的是s2在常量池中的地址,因为s2s1的字符串内容相同,所以在常量池中的地址也相同。
    所以输出的第二个结果为 true

    三、String类的特性分析

    (1) final 无论是String类、还是其中保存数据的 value[ ] 都是final类型的
    众所周知, final定义的变量有成为常量,在初始化之后就不能修改

    String str = "sunny";
    str = "day";
    
    • 1
    • 2

    这样是没有问题的,但是不是将原来字符串的内容修改了呢?
    在这里插入图片描述
    起初,在堆的常量池中,创建了sunny,并将引用对象指向这个地址;之后在常量池中检测是否存在day,如果不存在就创建这个字符串,然后将引用对象指向这个新的地址,存在就直接指向这个地址即可。
    所以说,并不是修改了原来的字符串,而是创建了一个新的对象

    (2) String类的字符串拼接
    第一种,几个字符串常量拼接

    String s1 = "hello" + "world";
    
    • 1

    这种只会创建一个对象,在常量池中保存 helloworld字符串,s1指向这个地址

    第二种,几个字符串对象拼接

    String str1 = "hello";
    String str2 = "world";
    String str3 = str1 + str2;
    
    • 1
    • 2
    • 3

    这种情况与第一种方式不同,因为 str1 和 str2是已经存在的字符串对象,它的实际创建过程是这样的:
    先会创建一个StringBuffer类的对象,然后调用两次 append()方法,将这两个字符串拼接到一起,最后调用 toString()方法,将StringBuffer类的对象转化为String类的对象,返回给str3。

    所以str3在内存中,实际是在堆中创建了一块空间,指向常量池的 helloworld,最后将堆中value[ ]的地址赋给 str3

    (3) 创建对象,调用方法,属性修改的内存分析

    public class Main{
    	String s = new String("powferful");
    	final char [] ch = {z, a, p, p, i, n, e, s, s};
    	public void change(String s, char [] ch){
    		s = "badly";
    		ch[0] = 'h';
    	}
    	public static void main (String [] args){
    		Main life = new Main();
    		life.change(life.s, life.ch);
    		System.out.println(life.s + " and " + life.ch);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    程序从主方法开始,创建对象是在堆中创建的,对象有两个属性,数组的空间也是在堆中分配的
    在这里插入图片描述
    当调用一个方法时,就会生成一个栈,此时执行change方法,在栈中生成了一个change的方法栈,其中对象s是通过直接赋值获得的,所以在常量池中创建对象badly,然后返回给 s;数组ch直接指向堆中的地址,并修改了它的第一个字符
    在这里插入图片描述
    当方法调用结束,该空间被释放,此时执行打印输出,调用的 s 和 ch仍然是主方法栈中的。
    所以输出, powerful and happiness

    四、String类的常用方法

    (1) String类是用于保存字符串常量的,每次更新都需要重新开辟空间,效率较低。

    String str1 = "perfect";
    String str2 = "Perfect";
    //区分大小写比较
    System.out.println(str1.equals(str2));
    //不区分大小写比较
    System.out.println(str1.equalsIgnoreCase(str2));
    //从前向后寻找
    System.out.println(str1.indexOf(e));
    //从后向前寻找
    System.out.println(str1.lastIndexOf(e));
    //获取字符串长度
    System.out.println(str1.length());
    //截取指定索引后的全部字符串
    System.out.println(str1.substring(3));
    //从指定索引开始截取指定范围的字符串 【此时为索引0-2】
    System.out.println(str1.substring(0, 3));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    方法名作用
    equals比较字符串内容是否相同
    equalsIgnoreCase不区分大小写比较内容是否相同
    length获取字符串长度
    indexOf返回字符串中第一次出现该字符的索引
    lastIndexOf返回字符串中最后一次出现该字符的索引
    substring根据指定索引截取字符串

    在这里插入图片描述
    (2) String类提供的第二组常用方法

    package com.zwh.java.string_;
    
    /**
     * @author Bonbons
     * @version 1.0
     */
    public class String01 {
        public static void main(String[] args) {
    /*
            //第一组方法
            String str1 = "perfect";
            String str2 = "Perfect";
            //区分大小写比较
            System.out.println(str1.equals(str2));
            //不区分大小写比较
            System.out.println(str1.equalsIgnoreCase(str2));
            //从前向后寻找
            System.out.println(str1.indexOf('e'));
            //从后向前寻找
            System.out.println(str1.lastIndexOf('e'));
            //获取字符串长度
            System.out.println(str1.length());
            //截取指定索引后的全部字符串
            System.out.println(str1.substring(3));
            //从指定索引开始截取指定个数的字符串
            System.out.println(str1.substring(0, 3));
    */
            //第二组方法
            String str3 = "Lucky";
            //转成大写
            System.out.println(str3.toUpperCase());
            //转成小写
            System.out.println(str3.toLowerCase());
            //拼接
            System.out.println(str3.concat(" day"));
            //替换
            System.out.println(str3.replace("Luck", "Suit"));
            //分割
            String poem = "两只黄鹂鸣翠柳,一行白鹭上青天";
            String [] p = poem.split(",");
            for(String s : p){
                System.out.println(s);
            }
            //转化为字符数组
            System.out.println(str3.toCharArray()[0]);
            //比较字符串大小,前者大返回正数,后者大返回负数,相等返回零
            //如果两个字符串,一个为其中另一个的前部分,那么返回的为两个字符串长度之差(前面-后面)
            String person1 = "jack";
            String person2 = "john";
            System.out.println(person1.compareTo(person2)); //一个不同字符的差值
            //格式化填充字符串
            String name = "小明";
            String sex = "男";
            int age = 18;
            double score = 88.888;
            //%.2f 会保留小数点后两位,而且还会进行四舍五入处理
            String strFormat = "我叫 %s, 性别 %s,今年 %d 岁, 期末成绩为 %.2f。";
            System.out.println(String.format(strFormat, name, sex, age, score));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    方法名作用
    toUpperCase将字符串中字母转化为大写
    toLowerCase将字符串中字母转化为小写
    concat拼接字符串
    replace将字符串中指定元素替换成新元素
    split根据指定字符进行分割,返回一个字符串数组
    toCharArray将字符串转化为字符数组
    compareTo比较字符串大小
    format由占位符组成的字符串,后面跟要填充的字符串

    在这里插入图片描述


    StringBuffer类

    • StringBuffer代表可变字符序列,可对字符串内容进行增删属于一个容器,很多方法与String类相同
    • StringBuffer保存的是字符串变量,可以更改里面的内容,不用每次都更新地址【只有在value[]内存不够时,才会开辟新空间,把原来的内容拷贝过去,然后更新地址】

    一、StringBuffer结构分析

    (1)StringBuffer类是final类型的,不能被继承

    (2)该类继承了AbstractStringBuilder,实际该类就是通过父类的 char [] value来存储字符串的

    (3)该类实现了Serializable接口,该类的对象可以串行化

    (4)StringBuffer字符内容是存储在 char [] value中,所以进行增加或删除操作时,不用每次都更换地址【创建新的对象】

    (5) StringBuffer的常用构造器

    • 默认创建一个大小为16的字符数组
    StringBuffer sb = new StringBuffer();
    
    • 1

    在这里插入图片描述

    • 根据传入的正整型参数,创建指定大小的字符串数组
    StringBuffer sb = new StringBuffer(30);
    
    • 1

    在这里插入图片描述

    • 根据传入的字符串,创建一个字符串长度+16的字符串数组
    StringBuffer sb = new StringBuffer("night");
    
    
    • 1
    • 2

    在这里插入图片描述

    二、StringBuffer的转换

    • String类转化为StringBuffer
    //利用构造器
    String s = "good";
    StringBuffer sb1 = new StringBuffer(s);
    //利用拼接
    StringBuffer sb2 = new StringBuffer();
    sb2.append(s);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • StringBuffer类转化为String
    //利用StringBuffer类提供的toString方法
    String s1 = sb1.toString();
    //利用构造器
    String s2 = new String(sb2);
    
    • 1
    • 2
    • 3
    • 4

    三、StringBuffer的常用方法

    方法名作用
    append(String s)添加字符串s(拼接)
    delete(int start, int end)删除索引 start <= index < end 处的字符串
    replace(int start, int end, String s)将[start,end)范围的字符串替换为字符串s
    indexOf(String s)查找指定子串s在字符串中第一次出现的位置
    lastIndexOf(String s)查找指定子串s在字符串中最后一次出现的位置
    insert(int index, String s)在索引index位置插入字符串s
    length()获取字符串的长度

    四、StringBuffer的应用

    (1) 利用StringBuffer构造器创建的对象和利用 append() 方法创建的对象有什么区别?

    String s = null;
    StringBuffer sb = new StringBuffer();
    sb.append(s);
    System.out.println(sb.length());
    System.out.println(sb);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 利用 append() 方法

    当传入的字符串对象为空时,append() 方法会判断是否为空串
    在这里插入图片描述
    如果为空,那么就会调用AbstractStringBuffer类的 appendNull() 方法
    在这里插入图片描述
    从该方法中,我们可以看出实际是添加了一个 null 的字符串
    之后正常输出,sb字符串的长度为4,输出内容 null

    • 利用构造器
    String s = null;
    StringBuffer sb = new StringBuffer(s);
    
    • 1
    • 2

    会产生空指针异常报错
    在这里插入图片描述
    在调用该构造器时,会获取字符串的长度,因为传入的为null,所以此处str也为空

    (2) 将从键盘获得的价格的整数部分每三位添加一个逗号【hhh,说实话有点像算法题】

    public class Main {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            String price = scanner.next();
            StringBuffer sb = new StringBuffer(price);
            //遍历寻找插入点
            for(int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3){
                //插入","
                sb.insert(i, ",");
            }
            System.out.println(sb);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述


    StringBuilder

    • StringBuilder 不是线程安全的,一般用于单线程的情况下,这种情况下比StringBuffer要快

    • StringBuilder类提供与StringBuffer类兼容的API,主要操作为appendinsert,可重载这些方法以接收任何类型的数据

    • StringBuilder类与StringBuffer类相同,继承了AbstractStringBuilder类,利用父类的字符数组存储可变的字符序列

    • StringBuilder类是final的,不允许被继承,实现了Serializable接口,其对象是可以串行化的【对象可以网络传输,可以保存到文件

    • StringBuilder的方法没有synchronized关键字【没有做互斥处理】,因此在单线程的情况下使用

    • StringStringBufferStringBuilder三者的比较:

    (1)String 不可变字符序列,效率低,重复率高
    (2)StringBuffer 可变字符序列,效率高,线程安全
    (3)StringBuilder 可变字符序列,效率最高,线程不安全


    Math

    • Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
    方法名作用
    abs求绝对值
    pow(a, b)求幂运算
    ceil向上取整
    floor向下取整
    round四舍五入
    sqrt求开方
    random求随机数
    max最大值
    min最小值
    • 应用案例:
    public class MathTest01 {
        public static void main(String[] args) {
            //求绝对值
            int num1 = -5;
            System.out.println("求-5的绝对值:" + Math.abs(num1));
            //求幂
            System.out.println("求2的3次幂:" + Math.pow(2,3));
            //向上取整
            double num2 = 3.54;
            System.out.println(num2 + "向上取整:" + Math.ceil(num2));
            //向下取整
            System.out.println(num2 + "向下取整:" + Math.floor(num2));
            //四舍五入
            System.out.println(num2 + "四舍五入的结果为:" + Math.round(num2));
            //求开方
            System.out.println("4开平方:" + Math.sqrt(4));
            //随机数
            System.out.println("生成1-10的随机数:" + Math.random()* 10);
            //最大值
            System.out.println(num1 + " and " + num2 + " 的最大值:" + Math.max(num1, num2));
            //最小值
            System.out.println(num1 + " and " + num2 + " 的最小值:" + Math.min(num1, num2));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述


    Arrays

    一、常用方法:

    方法名作用
    toString()返回数组的字符串形式
    sort将数组排序【正序或逆序】
    binarySearch可查找有序数组中的元素索引
    copyOf拷贝指定数组中指定个数的元素
    fill为数组填充相同的指定元素
    equals判断两个数组的元素是否完全相同
    asList将数组转化为集合【不能进行集合的操作】

    (1) toString() 方法

    public class ArraysTest {
        public static void main(String[] args) {
            //toString()方法,将数组转为字符串输出
            int [] num = {2, 5, 8, 0};
            System.out.println(Arrays.toString(num));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    实现原理:

        public static String toString(Object[] a) {
            if (a == null)
                return "null";
    
            int iMax = a.length - 1;
            if (iMax == -1)
                return "[]";
    
            StringBuilder b = new StringBuilder();
            b.append('[');
            for (int i = 0; ; i++) {
                b.append(String.valueOf(a[i]));
                if (i == iMax)
                    return b.append(']').toString();
                b.append(", ");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    对于数组类型,还可以为任意其他基础数据类型,若采用那些类型的数组,取值时用 a[i]即可。

    • 简述数组为空和长度为零的区别?
    int [] arr = null;
    int [] arr = new int[0];
    
    • 1
    • 2

    当数组不为空时,才能去判断长度。
    对于数组长度定义为零只是一种定义,对于存储本身没有意义,但是可以作为一些辅助作用。
    (2) sort() 方法

    public class ArraysTest {
        public static void main(String[] args) {
            int [] num = {2, 5, 8, 0};
            //sort()方法,将数组排序,最常见的是从小到大的排序
            Arrays.sort(num);
            System.out.println(Arrays.toString(num));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    数组是引用类型,排序操作会直接影响原数组

    实现逆序排序

    public class ArraysTest {
        public static void main(String[] args) {
    		//此处使用的包装类
            Integer[] num = {2, 5, 8, 0};
            Arrays.sort(num, 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(num));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    实现原理:
    1)Arrays.sort(arr, new Comparator())
    2)最终到TimSort类的 binarySort方法
    3)执行下面的代码,会根据动态绑定机制 c.compare()执行我们输入的匿名内部类

    while(left < right){
    	int mid = (left + right) >>> 1;
    	if(c.compare(pivot, a[mid]) < 0)
    		right = mid;
    	else
    		left = mid + 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    4)new Comparator(){
    	public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2;
                return i2 - i1;
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5)接口返回的值正负会决定是正序还是逆序

    (3) binarySearch() 方法

    class Main{
    	public static void main(String [] args){
    		int num = {0, 1, 2, 3, 4, 5, 8};
    		int index = Arrays.binarySearch(num, 3);
    		System.out.println("3的索引为:" + index);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    当数组中不存在目标值时,返回的值为该目标值应该在数组中的位置加一取反

    return -(low + 1);
    
    • 1

    假设目标值为6,那么如果存在该数组中的索引为6,索引方法返回 -7。

    (4)copyOf() 方法

    int [] n1 = {2, 1, 0};
    int [] n2 = Arrays.copyOf(n1, 2);
    System.out.println(Arrays.toString(n2));
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    如果拷贝个数小于零,那么就会报错
    如果拷贝个数大于原数组的大小,那么其余位置会补空 【null】

    (5) fill() 方法

    int [] num = new int[3];
    Arrays.fill(num,6);
    System.out.println(Arrays.toString(num));
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    为指定数组填充指定的元素,也可以覆盖掉原来的数组元素
    (6) equals() 方法

    int [] n1 = {1, 2, 3};
    int [] n2 = {1, 2, 3};
    System.out.println(Arrays.equals(n1, n2));
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    比较方法中的两个数组的元素是否完全相同,如果相同返回true,如果存在不同则返回false

    (7) asList() 方法

    int [] num = {1, 2, 3};
    List list = Arrays.asList(num);
    
    • 1
    • 2

    会根据传入的数组返回一个List类型的集合,编译类型为List接口,运行类型是这个接口中的一个内部类 ArrayList

    二、应用案例

    • 通过这个应用案例可以更好的理解上面 sort() 方法的逆序实现原理
    • 采用 冒泡 + binarySort 结合的方式实现的
    • 代码部分:
    import java.util.Arrays;
    import java.util.Comparator;
    
    /**
     * @author Bonbons
     * @version 1.0
     */
    public class ArraysSortCustom {
        public static void main(String[] args) {
            //初始化一个待排序的数组
            int [] num = {0, 3, 1, 5, 2, 8, 4};
            //调用排序方法
            bubbleSort(num, new Comparator(){
                @Override
                public int compare(Object o1, Object o2) {
                    //强转为整型数据后,采用自动拆箱转化为int类型
                    int i1 = (Integer)o1;
                    int i2 = (Integer)o2;
                    return i1 - i2;
                }
            });
            //打印数组
            System.out.println("排序后的数组为:" + Arrays.toString(num));
        }
        //创建一个冒泡+binarySort的方法
        public static void bubbleSort(int [] arr, Comparator c){
            //总共需要比较arr.length - 1 趟,每趟确定一个元素的位置
            for (int i = 0; i < arr.length - 1; i++) {
                //比较相邻两个元素的大小
                for (int j = 0; j < arr.length - 1; j++) {
                    //此时是正序排序
                    if(c.compare(arr[j], arr[j + 1]) > 0){
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述
    (2)通过书的价格来对书进行排序,该类包含两个属性 名字和价格。

    package com.zwh.java.math_;
    
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Comparator;
    
    /**
     * @author Bonbons
     * @version 1.0
     */
    public class ArraysTest {
        public static void main(String[] args) {
            Book [] books = new Book[4];
            books[0] =new Book("红楼梦",100);
            books[1] =new Book("金瓶梅",90);
            books[2] =new Book("青年文摘", 5);
            books[3] =new Book("java从入门到放弃w",30);
    
            //根据价格从小到大将书排序
            Arrays.sort(books, new Comparator<Book>() {
                @Override
                public int compare(Book o1, Book o2) {
                    double priceDiff = o1.getPrice() - o2.getPrice();
                    //逆序更改此处的值即可
                    if(priceDiff > 0)
                        return 1;
                    else if(priceDiff < 0)
                        return -1;
                    else
                        return 0;
                }
            });
            //输出Book类的信息
            System.out.println(Arrays.toString(books));
        }
    }
    
    class Book{
        private String name;
        private int price;
    
        //构造器
        public Book(){}
        public Book(String name, int price) {
            this.name = name;
            this.price = price;
        }
        //Get和Set方法
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(int price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    System

    方法名作用
    exit退出当前程序
    arraycopy拷贝数组元素
    currentTimeMillens返回当前时间
    gc垃圾回收机制

    (1)System.exit(int parameter)
    通过启动关闭序列来终止当前正在运行的虚拟机。
    状态参数为,代表正常退出;非零时代表异常终止。

    (2)System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
    //参数图片

    int [] newArr = new int[8];
            int [] curArr = {1, 2, 3, 4};
            System.arraycopy(curArr, 0, newArr, 0, 4);
            System.out.println(Arrays.toString(newArr));
    
    • 1
    • 2
    • 3
    • 4

    //运行截图

    (3)System.currentTimeMillis()
    返回当前时间与1970年1月1日凌晨之间的差值,一般以毫秒级为单位

    //可以用来测试一个代码块的运行时间
    long cur = System.currentTimeMillis();
    int count = 0;
    for(int i = 0; i < 10000000; i++){
          if(i % 2 == 0){
               count++;
          }
      }
    long cur2 = System.currentTimeMillis();
    System.out.println("运行该算法需要的时间为:" + (cur2 - cur) + "ms");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    (4) System.gc()

    • System.gc() 是Java提供的垃圾回收机制,当它被调用时,它将尽最大努力从内存中清理垃圾(未被引用的对象)。
    • 当调用该方法时,将触发完整的GC事件。在GC完成之前,整个JVM正在运行的所有服务都会被暂停。

    BigInteger 和 Decimal

    一、BigInteger

    • 当我们要存储一个特别大的数时,可以使用BigInteger类【利用字符串传入数据】
    • 当我们要对该类型的数据进行加减乘除时,要使用对应的方法,不能直接进行 + - * /
    • 如果要对BigInteger类进行运算,参与运算的两个对象都必须为BigInteger类型
    import java.math.BigInteger;
    public class BDMethod {
        public static void main(String[] args) {
            //存储一个大数,用long存储会提示Integer number too large
            BigInteger num = new BigInteger("8931741723712837");
            System.out.println(num);
            //对BigInteger类型的数据进行算术运算
            BigInteger num2 = new BigInteger("123");
            //加法采用add() 方法
            System.out.println(num.add(num2));
            //减法采用subtract()方法
            System.out.println(num.subtract(num2));
            //乘法采用multiply()方法
            System.out.println(num.multiply(num2));
            //除法采用divide()方法
            System.out.println(num.divide(num2));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、BigDecimal

    • 当我们需要保存一个精度很高的数时,我们可以采用BigDecimal类
    • 方法与BigInteger相同

    add() 加法
    subtract() 减法
    multiply() 乘法
    divide() 除法

    在使用除法因为可能会出现除不尽的时候,就会抛出异常,我们可以采用

    BigDecimal bd1 = new BigDecimal("1.231545623212315");
    BigDecimal bd2 = new BigDecimal("9.3124124515");
    System.out.println(bd1.divide(bd2, BigDecimal.ROUND_CEILING));
    
    • 1
    • 2
    • 3

    这样就会保留与分子相同的精度

    Date

    第一代日期类

    一、 Date类的关系图

    在这里插入图片描述
    Date类为第一代日期类,可以精确到毫秒级,但是现在其中很多方法和构造器已经被弃用,部分开发仍然会使用该类

    二、 Date类的时间格式

    采用的是国外的时间格式

    public class Date01 {
        public static void main(String[] args) {
            Date d1 = new Date();
            System.out.println(d1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    所以我们需要进行格式化,利用SimpleDateFormat的对象来完成格式化
    在这里插入图片描述
    对于格式化时,字母的使用大小写是有区别的,可以参考上面的表格

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
    System.out.println(sdf.format(d1));
    
    • 1
    • 2

    在这里插入图片描述

    三、 Date类的其他用法

    (1) 利用传入的毫秒数来设置时间 【不能超过长整型的范围】
    当前Date类还保留一个 public Date(Long date)的构造器,通过传入的一个长整型的毫秒数来获取时间。

    Date d2 = new Date(832490849);
    System.out.println(sdf.format(d2));
    
    • 1
    • 2

    如果为正数,那么为1970年1月1日以后的时间
    如果为负数,那么为1970年1月1日之前的时间
    在这里插入图片描述

    (2) 利用指定的字符串来设置时间 【获得的时间仍为Date类的初始格式】
    利用了SimpleDateFormat类的parse方法
    待转化的字符串的格式,要与创建的SimpleDateFormat类的对象格式相同

    String s = "2022年5月21日 00:00:00 星期六";
    //在主方法处抛出异常
    Date d3 = sdf.parse(s);
    System.out.println(d3);
    System.out.println(sdf.format(d3));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    此处通过主方法抛出了异常,因为该方法是这样的parse(String text, ParsePosition pos)

    text - A String ,其中一部分应解析。
    pos - 具有 ParsePosition的索引和错误索引信息的 ParsePosition对象。

    第二类日期类

    一、Calendar类的关系图

    在这里插入图片描述
    Calendar类是一个抽象类,我们通常使用的是它的私有无参构造方法
    通过提供的getInstance()来获得实例

    二、Calendar类的应用

    调用方法创建的该类对象,是将当前时间的所有信息都存储到该类的字段中

    Calendar c = Calendar.getInstance();
    System.out.println(c);
    
    • 1
    • 2

    在这里插入图片描述
    如果我们想直观的来查看时间,就要通过 get(字段) 方法从该对象中取出需要的字段信息

    System.out.println(c.get(Calendar.YEAR)+"年"
    +(c.get(Calendar.MONTH)+1)+"月"
    +c.get(Calendar.DAY_OF_MONTH)+"日"
    +c.get(Calendar.HOUR)+"时"
    +c.get(Calendar.MINUTE)+"分"
    +c.get(Calendar.SECOND)+"秒");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    Calendar类没有提供对应的格式化类,所以需要自己来完成需要的时间字段拼接【时间的格式自由度变高】
    在这里插入图片描述

    注意:该类中有许多字段,例如这样:HOUR 、HOUR_OF_DAY
    它们代表的含义是不同的,前者是12小时制,后者是24小时制
    类似的字段还有很多,可以根据需要选取

    第三代日期类

    Calendar类自由度很高的情况下,也出现很多问题:

    (1)可变性:日期与时间这样的类应该都是不可变的
    (2)偏移性:月份是从0月开始
    (3)格式化:格式化对Calendar类无法使用
    (4)线程不安全,不能处理润秒的问题(每隔2天多出1s)

    jdk8 之后,加入了第三代日期类
    LocalDate 代表年月日
    LocalTime 代表时分秒
    LocalDateTime 代表年月日 时分秒

    LocalDateTime为例

    一、LocalDateTime的关系图

    在这里插入图片描述
    该类实现了很多接口,只有一个构造器

    public LocalDateTime(LocalDate, LocalTime)
    
    • 1

    我们一般通过该类提供的now() 方法来利用当前时间返回LocalDateTime的对象

    public class Main{
        public static void main(String[] args) {
            LocalDateTime dlt1 = LocalDateTime.now();
            System.out.println(dlt1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    二、LocalDateTime的几个方法

    该类提供了很多方法,此处选取几个为例,具体可以参考相关JDK的api

    public class LocalDate01 {
        public static void main(String[] args) {
            LocalDateTime dlt1 = LocalDateTime.now();
            System.out.println(dlt1);
            //常见方法
            System.out.println("年 = " + dlt1.getYear());
            System.out.println("月 = " + dlt1.getMonthValue());
            System.out.println("日 = " + dlt1.getDayOfMonth());
            System.out.println("时 = " + dlt1.getHour());
            System.out.println("分 = " + dlt1.getMinute());
            System.out.println("秒 = " + dlt1.getSecond());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    对于月的获取有两个方法 getMonth() 与 getMonthValue(),前者返回的是字符串【英文月份】,后者显示的是数字【第几个月】

    对当前日期进行算术运算(加、减

    LocalDateTime ldt1 = LocalDateTime.now();
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss E");
            System.out.println("当前时间为: " + dtf.format(ldt1));
            System.out.println("十年之后的日子: " + dtf.format(ldt1.plusYears(10)));
            System.out.println("五个月前的日子: " + dtf.format(ldt1.minusMonths(5)));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    三、LocalDateTime类的格式化

    SimpleDateFormat类似,DateTimeFormatter为该类提供格式化

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss");
    String s = dtf.format(dlt1);
    System.out.println(s);
    
    • 1
    • 2
    • 3

    在创建DateTimeFormatter对象时,利用了该类的ofPattern()方法,使用指定的模式创建格式化程序。
    在利用该对象调用format方法将LocalDateTime类型的时间格式化
    在这里插入图片描述

    四、LocalDateTime的时间戳

    Instant时间戳与第一代时间Date类似,可以与其相互转换
    利用静态方法now()获取当前时间戳的对象

    Instant now = Instant.now();
    System.out.println(now);
    
    • 1
    • 2

    将时间戳对象转化为Date对象

    Date date = Date.from(now);
    
    • 1

    将Date对象转化为时间戳对象

    Instant instant = date.toInstant();
    
    • 1
  • 相关阅读:
    canal+es+kibana+springboot
    Commvault+XSKY 推出基于 Object Lock 的防勒索病毒联合方案
    线性回归模型
    windows ,C ,thread、
    jmeter
    链表
    2022.11.22Longest Ordered Subsequence POJ - 2533
    JS 点击气泡卡片自身外的区域自动关闭的代码逻辑
    剑指 Offer 28. 对称的二叉树
    【工具门户】Backstage配置使用PostgreSQL(三)
  • 原文地址:https://blog.csdn.net/qq_61323055/article/details/126291107