Java包装类与工具类

包装类

  • 在面向对象当中一切皆对象
  • 基本数据类型变量不是对象,比如 int a = 10; 当中就没有对象,所以就很矛盾
  • 此时我们就可以对基本数据类型进行包装,把基本数据类型包装为一个对象
  • 把基本数据类型变的更强大,以面向对象的思想来去使用这些类型

🐤对基本数据类型包装的好处

  • 使用包装类后,功能变的更加强大
    • 以前使用double来去表示一个人的分数
    • 此时这个人的分数考了0分,可以表示0.0
    • 如果这个人没有来考试,那就代表没有分数 使用包装类型后, 即可表示这两种状态一个0.0 一个 是null
    • 基本数据类型就办不到
  • 包装类当中给我们提供了很多方法,可以直接使用
    • 我们要将一个数据转成二进制
    • 使用包装对象后, 就可以直接调用方法算出来
    • 不需要我们再去手动去算
  • 对基本数据类型进行了增加 → 每一个基本数据类型都对应一个包装类
  • 有了包装类之后, 可以以对象的方式来使用这些类型

装箱操作

把基本数据类型变成 包装类

public class Demo {
    public static void main(String[] args) {
        int age = 10;
        Integer num = Integer.valueOf(age);

        System.out.println(num.TYPE);
        System.out.println(num.MAX_VALUE);
        System.out.println(num.MIN_VALUE);
        System.out.println(num);
    }
}
  • Integer内部覆盖了toString
  • Integer.TYPE可以用来知道这个包装类是由什么基本数据类型转换过来的
  • Integer.MAX_VALUE可以得知最大存储范围值
  • Integer.MIN_VALUE可以得知最小存储范围值

可以把一个字符串转成Integer类型 字符串当中必须得是数字

public class Demo {
    public static void main(String[] args) {
        Integer age = Integer.valueOf("10");
        System.out.println(age);
    }
}

可以把整数转成二进制

public class Demo {
    public static void main(String[] args) {
        Integer age = Integer.valueOf("10");
        System.out.println(Integer.toBinaryString(age));
    }
}

基本数据类型对应的包装类

自动装箱

可以直接把一个基本数据类型的值赋值给包装类对象

public class Demo {
    public static void main(String[] args) {
        Integer age = 10;
        System.out.println(age);
    }
}

拆箱操作

把包装类对象转成对应的基本数据类型我们称为拆箱

public class Demo {
    public static void main(String[] args) {
        Integer num = Integer.valueOf(15);
        int newNum =  num.intValue();
        System.out.println(newNum);
    }
}

自动拆箱

可以直接把一个包装类对象赋值给基本数据类型的变量

public class Demo {
    public static void main(String[] args) {
        Integer num = Integer.valueOf(15);
        int newNum =  num;
        System.out.println(newNum);
    }
}

🦄字符串与基本数据类型和包装类型的转换

包装类valueof缓存设计

  • 当使用valueof创建一个包装类,它内部的实现会先从缓存当中查看是否已经有该存在匹配条件的值
  • 如果有就直接返回,不会再去创建新的地址。如果没有,就去创建新的地址

main方法

当点击运行时,JVM自动会调用main方法

🐤参数与修饰符介绍

  • public:被JVM调用的方法,它的权限要足够的大
  • static:被JVM调用的方法, 不需要创建对象,直接使用类名调用
  • void:被JVM调用的方法,不需要有任何的返回值
  • main:方法的名称,只能这样写,不然JVM识别不了
  • String[] args:运行时传递的参数

以上是配置main方法运行时传递的参数,可以在main方法中打印一下,配置的是对应类的main方法参数

public class Demo {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
    }
}

System类

Scanner类

等待从键盘录入一个数

public class Demo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        String str = scanner.nextLine();

        System.out.println(num);
        System.out.println(str);
    }
}

如果使用的Scanner是同一个对象进行录入不能换行输入,需要在一行当中输入,如果需要再起一行需要在创建新的Scanner对象

System类

拷贝数组

  • System.arraycopy

参数

  • src:源数组
  • srcPos:源数组中的起始位置
  • dest:目标数组
  • destPos:目标数组中的起始位置
  • length:要复制的元素的数量
public class Demo {
    public static void main(String[] args) {
        int[] src = {1,2,3,4,5,6};
        int[] dest = new int[10];
        System.arraycopy(src, 2, dest, 1, 4);
        System.out.println(Arrays.toString(src));
        System.out.println(Arrays.toString(dest));
    }
}

终止当前正在运行的 Java 虚拟机

  • System.exit(0):正常退出
public class Demo {

    static void test(){
        System.out.println("BNTang");
        System.exit(0);
    }

    public static void main(String[] args) {
        test();
        System.out.println("JonathanTang");
    }
}
  • System.exit(1):非正常退出(异常退出)
public class Demo {

    static void test(){
        System.out.println("BNTang");
        System.exit(1);
    }

    public static void main(String[] args) {
        test();
        System.out.println("JonathanTang");
    }
}

运行垃圾回收器

当一个对象被垃圾回收时,自动调用的一个方法

@Override
protected void finalize() throws Throwable {
    super.finalize();
    System.out.println("我被回收了");
}

当一个对象,没有人引用时,就会被自动垃圾回收器回收,被自动垃圾回收器回收的内容,并不是立马就从内存当中来抹去,在某一时刻,才去从内存当中会抹去,当对象被回收时,会自动调用一个方法finalize

class Person{
    String name;
    Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("我被回收了");
    }
}

public class Demo {

    public static void main(String[] args) {
        Person person = new Person("BNTang", 23);
        person = null;
    }
}

System.gc();

class Person{
    String name;
    Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("我被回收了");
    }
}

public class Demo {

    public static void main(String[] args) {
        Person person = new Person("BNTang", 23);
        person = null;
        System.gc();
    }
}

Math类

求两个数最大值

public class Demo {
    public static void main(String[] args) {
        int res = Math.max(10, 20);
        System.out.println(res);
    }
}

求两个数最小值

public class Demo {
    public static void main(String[] args) {
        int res = Math.min(10, 20);
        System.out.println(res);
    }
}

返回一个随机数(0-1不包含1)

public class Demo {
    public static void main(String[] args) {
        double res = Math.random();
        System.out.println(res);
    }
}

返回0到100之间的随机整数

public class Demo {
    public static void main(String[] args) {
        int res = (int) (Math.random() * 100);
        System.out.println(res);
    }
}

开平方根

public class Demo {
    public static void main(String[] args) {
        double res = Math.sqrt(4);
        System.out.println(res);
    }
}

大精度小数

金额用什么数据类型

  • 不是doube,更不是float,而是用BigDecimal
  • 对于金融项目,对于金额,误差是不能容忍的
  • Java 中 float 的精度为 6-7 位有效数字。double 的精度为 15-16 位
  • BigDecimal 用来对超过16位有效位的数进行精确的运算

🐤常用方法

方法名 作用
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象
toString() 将BigDecimal对象的数值转换成字符串
doubleValue() 将BigDecimal对象中的值以双精度数返回
floatValue() 将BigDecimal对象中的值以单精度数返回
public class Demo {
    public static void main(String[] args) {
        double d1 = 11000;
        double d2 = 0.35;
        System.out.println("错误的:" + d1 * d2);

        BigDecimal bigDecimal1 = new BigDecimal(11000);
        BigDecimal bigDecimal2 = BigDecimal.valueOf(0.35);
        System.out.println("正确的:" + bigDecimal1.multiply(bigDecimal2));
    }
}

String类

也就是字符串,把多个字符串连一起

字符串本质

  • 在JDK9.0之前
    • 其它是一个char[]数组
    • private final char value[];
    • 根据UTF-16,JAVA的内部编码格式,编译成了class文件,然后送给JVM执行
    • 一个UTF-16字符占2个字节,不管是什么样的char都是2个字节
  • 存在的问题
    • JDK8的字符串存储在char类型的数组里面
    • 在大多数情况下,char类型只需要一个字节就能表示出来了
    • 比如各种字母什么的,两个字节存储势必会浪费空间
    • JDK9的一个优化就在这,内存的优化
  • JDK9.0
    • private final byte[] value;
    • JDK9是由byte类型的数组来进行存储的
    • 在JDK9的String类中,维护了这样的一个属性coder,它是一个编码格式的标识,使用LATIN1还是UTF-16

public class Demo {
    public static void main(String[] args) {
        String name = "灰灰";
        String str = "a";
    }
}

String的创建

  • 直接赋值
String name = "BNTang";
  • 通过构造器来创建
String name = new String("BNTang");

字符串的比较

  • ==:比较两个字符串的内存地址是否相等
  • equals:判断两个字符串的值是否相同
public class Demo {
    public static void main(String[] args) {
        String name = "灰灰";
        String str = "a";

        System.out.println(name.equals(str));
        System.out.println(name == str);
    }
}

JDK9中equals源码分析

  1. 判断传入的对象是否与当前对象相等,相等就直接返回true

  1. 如果不等再判断传入对象是否为String

  • 如果是,强制转换成String

  • 判断当前的编码和传入的编码是否一致

  • 如果编码不一样, 两个直接判定不相等,也就是结束了
  • 如果相等,再判断是StringLatin1还是StringUTF16

  • 判断完成之后, 再根据结果调用对应的equals

  • 这里我就以StringLatin1.equals来举例了
  • 判断两个字符串的长度是否相等

  • 如果相等,逐一的来判断里面的字符是否相等

  • 如果都相等结果就是true

  • 有一个不相同结果就是false

StringUTF16.equals源码

@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        int len = value.length >> 1;
        for (int i = 0; i < len; i++) {
            if (getChar(value, i) != getChar(other, i)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

StringLatin1.equals源码

@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        for (int i = 0; i < value.length; i++) {
            if (value[i] != other[i]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

常量池

public class Demo {
    public static void main(String[] args) {
        String name = "BNTang";
        String str = "BNTang";
        String newStr = new String("BNTang");

        System.out.println(name == str);
        System.out.println(name == newStr);
    }
}

字符串对象值为空

  • 表示引用为空
 String str = null;
  • 还没有初始化,没有分配内存空间

表示空字符串

String  str = "";
  • 已经创建了对象,已经分配了内存,内容为空

字符串常用方法

public class Demo {
    public static void main(String[] args) {
        char[] cs = new char[] {'A','B','C'};
        String str = new String(cs);
        System.out.println(str);

        char[] cs2 = str.toCharArray();
        System.out.println(cs2);

        String str2 = "BNTang";
        System.out.println(str2.length());
        System.out.println(str2.charAt(2));

        String str3 = "ABCDEFCDGCD";
        String str4 = "CD";
        System.out.println(str3.indexOf(str4));
    }
}

public class Demo {
    public static void main(String[] args) {
        String str3 = "ABCDEFCDGCD";
        String str4 = "CD";
        System.out.println(str3.lastIndexOf(str4));

        String str5 = "cd";
        System.out.println(str5.toUpperCase());
        System.out.println(str3.toLowerCase());

        System.out.println(str4.equalsIgnoreCase(str5));

        String str = "BNTang;JonathanTang;XiaoHuiHui;";
        String[] res = str.split(";");
        System.out.println(Arrays.toString(res));
    }
}

public class Demo {
    public static void main(String[] args) {
        String str = "BNTang";
        boolean res = str.startsWith("BN");

        System.out.println(res);

        String resTwo = str.substring(1);
        System.out.println(resTwo);

        String strThree = str.substring(1, 4);
        System.out.println(strThree);

        String strTwo = "xhh";
        String nameStr = strTwo.substring(0, 1);
        System.out.println(nameStr);

        nameStr = nameStr.toUpperCase();
        System.out.println(nameStr);
        String lastStr = strTwo.substring(1);
        System.out.println(lastStr);
        System.out.println(nameStr + lastStr);
    }
}

public class Demo {
    public static void main(String[] args) {
        String s = " dsakjh xjcvyu ";
        s = s.trim();
        System.out.println(s.length());
        System.out.println(s);

        String str = "vxcivojdsau";

        String newStr = str.replace("j", "B");
        System.out.println(newStr);

        String strTwo = " BN Tang ";
        strTwo = strTwo.replace(" ", "");
        System.out.println(strTwo);
    }
}

字符串分类

不可变字符串String:定义好之后,就不能再去改变了(内存地址不可变)

可变的字符串:定义好之后,还可以进行修改,改变时,不会创建新的内存地址

可变字符串

  • StringBuilder:是没有synchronized效率高一些
  • StringBuffer:方法前面多了一个synchronized加锁,更安全,效率低了一些

效率测试

String

public class Demo {
    static void testString(){
        long begin = System.currentTimeMillis();
        String str = "";
        for(int i = 0; i <= 10000; i++) {
            str += i;
        }
        long last = System.currentTimeMillis();
        long res = last - begin;
        System.out.println(res);
    }

    public static void main(String[] args) {
        // 188
        testString();
    }
}

StringBuilder

public class Demo {
    static void testBuilder() {
        long begin = System.currentTimeMillis();
        StringBuilder str = new StringBuilder();
        for(int i = 0; i <= 10000; i++) {
            str.append(i);
        }
        long last = System.currentTimeMillis();
        long res = last - begin;
        System.out.println(res);
    }

    public static void main(String[] args) {
        // 3
        testBuilder();
    }
}

StringBuffer

public class Demo {
    static void testBuffer() {
        long begin = System.currentTimeMillis();
        StringBuffer str = new StringBuffer();
        for(int i = 0; i <= 10000; i++) {
            str.append(i);
        }
        long last = System.currentTimeMillis();
        long res = last - begin;
        System.out.println(res);
    }

    public static void main(String[] args) {
        // 4
        testBuffer();
    }
}

StringBuilder创建方法的使用,创建的可变字符串,初始容量为16,如果超过的话,它会自动扩容,可变字符串,本质 还是一个char类型的数组

Random类

生成随机数

相同的种子,生成的随机数是一样的

public class Demo {
    public static void main(String[] args) {
        Random r = new Random();
        int res = r.nextInt();
        System.out.println(res);
        System.out.println(r.nextDouble());
        System.out.println(r.nextBoolean());
        
        Random r2 = new Random(110);
        Random r3 = new Random(110);
        System.out.println(r2.nextInt());
        System.out.println(r3.nextInt());
    }
}

生成34到179之间的随机数

public class Demo {
    public static void main(String[] args) {
        Random random = new Random();
        System.out.println(34 + random.nextInt(145));
    }
}

生成5位随机数

public class Demo {
    public static void main(String[] args) {
        String res =  UUID.randomUUID().toString();
        System.out.println(res);
        res = res.substring(0,5);
        System.out.println(res);
    }
}

UUID

  • 通用唯一识别符
  • 在一台机器上生成的数字
  • 当前的时间,跟当前电脑网卡生成一段字符
public class Demo {
    public static void main(String[] args) {
        String uuid = UUID.randomUUID().toString();
        System.out.println(uuid);
    }
}

生成验证码

public class Demo {
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        str.append(str.toString().toLowerCase());
        str.append("0123456789");
        System.out.println(str);
        System.out.println(str.length());
        StringBuilder sb = new StringBuilder(5);
        for(int i = 0; i < 5; i++) {
            int index = new Random().nextInt(str.length());
            char ch = str.charAt(index);
            sb.append(ch);
        }
        System.out.println(sb);
    }
}

Date日期类

创建日期

public class Demo {
    public static void main(String[] args) {
        // 创建一个日期对象
        Date date = new Date();
        System.out.println(date);
        
        // 获取当前时间的毫秒
        long curTime = System.currentTimeMillis();
        
        // 把一个毫秒值转成日期类型
        Date date2 = new Date(curTime);
        System.out.println(date2);
        
        // 中国人喜欢风格
        String str = date2.toLocaleString();
        System.out.println(str);
        
        // 把一个日期类型转成毫秒值
        System.out.println(date2.getTime());
    }
}

日期格式化

public class Demo {
    public static void main(String[] args) {
        // 日期格式化
        Date date = new Date();
        System.out.println(date);
        System.out.println(date.toLocaleString());
        
        // 单例格式化器
        DateFormat df =  DateFormat.getInstance();

        // 对指定的日期进行格式化
        String time = df.format(date);
        System.out.println(time);
    }
}

自定义日期格式

public class Demo {
    public static void main(String[] args) {

        Date date = new Date();

        // 自定义格式化器
        SimpleDateFormat sf = new SimpleDateFormat();
        sf.applyPattern("yyyy-MM-dd hh:mm:ss");

        String format = sf.format(date);
        System.out.println(format);
    }
}

日期格式化对照表

相关资料

posted @ 2020-08-23 09:58  BNTang  阅读(234)  评论(0编辑  收藏  举报