包装类

  • 在面向对象当中​​一切皆对象​
  • 基本数据类型变量不是对象,比如 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));
}
}

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

Java包装类与工具类_基本数据类型

自动装箱

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

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);
}
}

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

Java包装类与工具类_包装类_02

包装类valueof缓存设计

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

Java包装类与工具类_基本数据类型_03

main方法

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

????参数与修饰符介绍

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

Java包装类与工具类_字符串_04

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

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

System类

Scanner类

等待从键盘录入一个数

Java包装类与工具类_字符串_05

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对象

Java包装类与工具类_包装类_06

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

Java包装类与工具类_字符串_07

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

Java包装类与工具类_基本数据类型_08

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​

Java包装类与工具类_包装类_09

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

Java包装类与工具类_包装类_10

  • 如果是,强制转换成String

Java包装类与工具类_基本数据类型_11

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

Java包装类与工具类_基本数据类型_12

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

Java包装类与工具类_基本数据类型_13

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

Java包装类与工具类_基本数据类型_14

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

Java包装类与工具类_基本数据类型_15

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

Java包装类与工具类_基本数据类型_16

  • 如果都相等结果就是true

Java包装类与工具类_字符串_17

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

Java包装类与工具类_字符串_18

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;
}

常量池

Java包装类与工具类_基本数据类型_19

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 = "";
  • 已经创建了对象,已经分配了内存,内容为空

字符串常用方法

Java包装类与工具类_字符串_20

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));
}
}

Java包装类与工具类_字符串_21

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));
}
}

Java包装类与工具类_基本数据类型_22

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);
}
}

Java包装类与工具类_字符串_23

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);
}
}

Java包装类与工具类_基本数据类型_24

字符串分类

不可变字符串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);
}
}

日期格式化对照表

Java包装类与工具类_字符串_25

Java包装类与工具类_基本数据类型_26

相关资料

  • ​​Java实用的工具类​​