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源码分析
- 判断传入的对象是否与当前对象相等,相等就直接返回
true
- 如果不等再判断传入对象是否为
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);
}
}
日期格式化对照表