学习日记-day16-5.26
完成目标:
知识点:
1.经典接口
基本数据类型的数据(除boolean类型外)需要比较大小使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。
Java给所有引用数据类型的大小比较,指定了一个标准接口:java.lang.Comparable接口
-
需要比较大小的类实现java.lang.Comparable接口
-
重写compareTo方法,定义比较规则
package java.lang;public interface Comparable{int compareTo(Object obj);
}
知识点 | 核心内容 | 重点 |
Comparable接口 | 通过实现compareTo(Object o)方法定义对象自然排序规则; this对象与参数对象比较 | 1. 返回值规则:this-参数>0返回正整数(当前对象大); 2. 必须强制类型转换参数对象 |
Comparator接口 | 通过compare(Object o1, Object o2)方法定义灵活比较规则; 独立于比较类的外部比较器 | 1. 双参数比较:o1-o2>0返回正整数(o1大); 2. 两个参数都需要强制类型转换 |
比较场景 | 1. 引用数据类型排序; 2. 集合框架中的排序操作 | 易混淆: - Comparable是类内部实现; - Comparator是外部比较器类 |
冒泡排序应用 | 通过比较器返回值控制排序方向; students[i].compareTo(students[i+1])>0时交换位置 | 关键代码: return this.getScore()-((Student)o).getScore() |
返回值语义 | >0:前者大于后者; <0:前者小于后者; =0:两者相等 | 易错点: 比较对象属性时忘记类型转换 |
典型应用场景 | 1. 学生成绩排序; 2. 商品价格排序; 3. 日期对象比较 | 重点: 两种接口的实现方式差异 |
2.String
知识点 | 核心内容 | 重点 |
String类概述 | Java中所有双引号字符串字面值均为String类的实例(对象),可直接创建无需new | 字符串字面值本质是对象,但语法简化 |
String不可变性 | 字符串创建后值不可更改(底层为final修饰的数组),拼接操作会生成新对象 | s += "world"实际产生新对象,原字符串不变 |
字符串共享机制 | 相同字面值的字符串对象可共享(如s1="ABC"和s2="ABC"指向同一内存) | ==比较地址值,equals()比较内容 |
底层实现演变 | JDK8:final char[]; JDK9+:final byte[](节省内存空间) | 数组地址被final固定导致字符串不可变 |
String vs StringBuilder | String适用于常量字符串;StringBuilder适用于频繁修改的字符串 | 面试高频:内存效率与操作性能对比 |
隐含面试题 | 1. String s = "a" + "b"编译期优化机制; 2. 字符串常量池与堆内存关系 | 编译优化与运行时内存分配差异 |
3.String的创建
public class Demo02String {public static void main(String[] args) {//1.String() -> 利用String的无参构造创建String对象String s1 = new String(); //System.out.println(s1);//2.String(String original) -> 根据字符串创建String对象String s2 = new String("abc");System.out.println(s2);//3.String(char[] value) -> 根据char数组创建String对象char[] chars = {'a','b','c'};String s3 = new String(chars);System.out.println(s3);/*4.String(byte[] bytes) -> 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String*/byte[] bytes1 = {97,98,99};String s4 = new String(bytes1);System.out.println(s4);byte[] bytes2 = {-97,-98,-99};String s5 = new String(bytes2);System.out.println(s5);byte[] bytes3 = {-28,-67,-96};String s6 = new String(bytes3);System.out.println(s6);//5.简化形式String s7 = "abc";System.out.println(s7);}
}1.String(char[] value, int offset, int count)->将char数组的一部分转成String对象 value:要转String的char数组offset:从数组的哪个索引开始转count:转多少个
2.String(byte[] bytes, int offset, int length)->将byte数组的一部分转成String对象 bytes:要转String的byte数组offset:从数组的哪个索引开始转length:转多少个public class Demo03String {public static void main(String[] args) {/* 1.String(char[] value, int offset, int count)->将char数组的一部分转成String对象value:要转String的char数组offset:从数组的哪个索引开始转count:转多少个*/char[] chars = {'a','b','c','d','e','f'};String s1 = new String(chars,1,3);System.out.println(s1);/* 2.String(byte[] bytes, int offset, int length)->将byte数组的一部分转成String对象bytes:要转String的byte数组offset:从数组的哪个索引开始转length:转多少个*/byte[] bytes = {97,98,99,100,101};String s2 = new String(bytes,0,2);System.out.println(s2);}
}
知识点 | 核心内容 | 重点 |
String构造方法 | 通过无参构造、字符串直接赋值、char数组、byte数组等方式创建String对象 | 无参构造创建空字符串 vs 直接赋值空字符串"" |
char数组构造 | new String(char[] chars) 将整个char数组转为字符串 | 数组索引从0开始,需注意越界问题 |
byte数组构造 | new String(byte[] bytes) 使用平台默认字符集(实际受IDE影响为UTF-8)解码 | 负数字节可能对应中文(UTF-8中3字节=1中文); 正数字节直接转ASCII字符 |
部分数组转换 | new String(char[] chars, int offset, int count) 从指定索引开始转换指定长度的字符 | offset起始位置包含在结果中,count需严格匹配有效范围 |
简化形式 | 直接赋值(如String s = "ABC")是最常用方式 | IDE自动补全可能导错包(需确认java.lang.String) |
编码差异 | 操作系统默认GBK(中文占2字节) vs IDE强制UTF-8(中文占3字节) | 字节数组转字符串时需统一编码,否则乱码 |
IDE影响 | IDEA启动参数强制UTF-8,覆盖平台默认字符集 | 实际开发环境与理论差异需特别注意 |
4.String知识点
知识点 | 核心内容 | 重点 |
字符串创建与内存分配 | String s1="ABC"直接指向常量池,String s3=new String("ABC")在堆中创建新对象,但内容共享常量池的"ABC" | s1==s2为true(常量池共享),s1==s3为false(new强制新地址) |
字符串对象数量分析 | new String("ABC")可能创建1个(常量池已存在"ABC")或2个对象(常量池无"ABC"时先创建字面量) | 笔试需区分“共有对象数”和“实际创建对象数” |
字符串拼接机制 | 字面量拼接(如"hello"+"world")编译期优化为"helloworld"(不产生新对象);含变量的拼接(如s1+s2)触发StringBuilder生成新对象 | s3==s4为true(字面量优化),s3==s5/s6为false(变量拼接必new) |
反编译验证原理 | 通过反编译工具可观察到:变量拼接代码被转换为StringBuilder的new操作,直接证明内存分配差异 | 实际笔试中需结合JVM常量池规则和编译优化行为分析 |
5.判断字符串内容
已知用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录成功与否,给出相应的提示
步骤:1.先定义两个字符串,表示注册过的用户名和密码2.创建Scanner对象,键盘录入用户名和密码3.比较,如果输入的用户名和密码跟已经注册过的用户名和密码内容一样,就登录成功,否则就登录失败public class Demo02String {public static void main(String[] args) {//1.先定义两个字符串,表示注册过的用户名和密码String username = "root";String password = "123";//2.创建Scanner对象,键盘录入用户名和密码Scanner sc = new Scanner(System.in);for (int i = 0; i < 3; i++) {System.out.println("请您输入用户名:");String name = sc.next();System.out.println("请您输入密码:");String pwd = sc.next();//3.比较,如果输入的用户名和密码跟已经注册过的用户名和密码内容一样,就登录成功,否则就登录失败if (name.equals(username) && pwd.equals(password)) {System.out.println("登录成功");break;} else {if (i == 2) {System.out.println("账号冻结");} else {System.out.println("登录失败!");}}}}
}===============================================================================public class Demo03String {public static void main(String[] args) {//String s = "abc";String s = null;//method(s);String s1 = null;String s2 = "abc";method01(s1,s2);}/*工具类:Objects方法:判断两个对象是否相等 -> 自带防空指针作用public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b));}*/private static void method01(String s1, String s2) {if (Objects.equals(s1,s2)){System.out.println("是abc");}else{System.out.println("不是abc");}}/*如果传递过来的对象是null,再去点其他方法,就会空指针解决:不要让一个字符串变量去点,用确定的字符串去点,可以防空*/private static void method(String s) {/*if (s.equals("abc")){System.out.println("是abc");}else{System.out.println("不是abc");}*/if ("abc".equals(s)){System.out.println("是abc");}else{System.out.println("不是abc");}}}
知识点 | 核心内容 | 重点 |
String.equals()方法 | 比较字符串内容(区分大小写) | 返回值是布尔类型,比较的是内容而非地址 |
String.equalsIgnoreCase()方法 | 比较字符串内容(忽略大小写) | 仅适用于字母字符,数字/繁简体不适用 |
字符串比较的防空技巧 | 将常量字符串放在equals()方法调用方 | 开发实战技巧:"ABC".equals(s)可避免空指针 |
Objects.equals()工具方法 | 比较两个对象是否相等(自动防空) | 位于java.util.Objects类,可处理双变量比较 |
用户登录案例实现 | 三次登录机会控制流程 | 循环结构与字符串比较的综合应用 |
账号锁定机制 | 第三次失败后提示账号冻结 | 通过循环计数器(i==2)判断最终尝试 |
6.String获取方法
public class Demo04String {public static void main(String[] args) {String s1 = "abcdefg";//int length() -> 获取字符串长度System.out.println(s1.length());//String concat(String s)-> 字符串拼接,返回新串儿System.out.println(s1.concat("haha"));//char charAt(int index) -> 根据索引获取对应的字符System.out.println(s1.charAt(0));//int indexOf(String s) -> 获取指定字符串在大字符串中第一次出现的索引位置System.out.println(s1.indexOf("a"));//String subString(int beginIndex) -> 截取字符串,从指定索引开始截取到最后,返回新串儿System.out.println(s1.substring(3));//String subString(int beginIndex,int endIndex) -> 截取字符串,从beginIndex开始到endIndex结束//含头不含尾,返回新串儿System.out.println(s1.substring(1,6));}
}
知识点 | 核心内容 | 重点 |
长度获取 | 使用 length() 方法获取字符串长度(如 s1.length()) | length 是方法(带括号),数组的 length 是属性 |
字符串拼接 | concat() 方法拼接字符串,返回新字符串(原字符串不可变) | 返回新串,原串不变 |
字符索引获取 | charAt(index) 根据索引获取对应字符(索引从 0 开始) | 越界会报错 |
子串查找 | indexOf(str) 返回子串首次出现的索引位置 | 仅返回第一次匹配的索引 |
字符串截取 | substring(beginIndex) 或 substring(beginIndex, endIndex) 截取子串 | 含头不含尾 |
字符串遍历 | 通过循环和 charAt() 遍历字符串字符 | 索引从 0 到 length()-1 |
7.String的转换功能
1.char[] toCharArray() -> 将字符串转成char数组
2.byte[] getBytes() -> 将字符串转成byte数组
3.String replace(CharSequence c1,CharSequence c2)-> 替换字符CharSequence->String的接口
4.byte[] getBytes(String charsetName) -> 按照指定的编码将字符串转成byte数组 public class Demo06String {public static void main(String[] args) throws UnsupportedEncodingException {String s = "abcdefg";//1.char[] toCharArray() -> 将字符串转成char数组char[] chars = s.toCharArray();for (int i = 0; i < chars.length; i++) {System.out.println(chars[i]);}System.out.println("===============");//2.byte[] getBytes() -> 将字符串转成byte数组byte[] bytes = s.getBytes();for (int i = 0; i < bytes.length; i++) {System.out.println(bytes[i]);}System.out.println("===============");//3.String replace(CharSequence c1,CharSequence c2)-> 替换字符 CharSequence->String的接口System.out.println(s.replace("a","z"));System.out.println("===============");//4.byte[] getBytes(String charsetName) -> 按照指定的编码将字符串转成byte数组byte[] bytes1 = "你好".getBytes("GBK");for (int i = 0; i < bytes1.length; i++) {System.out.println(bytes1[i]);}}
}键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)
步骤:1.创建Scanner对象,键盘录入2.定义三个变量,用来统计3.调用next方法录入一个字符串,遍历字符串,将每一个字符拿出来4.统计大写字母A-Z -> 65-90比如:B -> 66 -> 在65-90之间,证明就是大写字母5.统计小写字母a-z -> 97-122比如:b -> 98 -> 在97-122之间,证明就是小写字母6.统计数字:0-9 -> 48-57比如:字符1 -> 49 -> 在48-57之间,证明就是数字7.将统计结果打印出来public class Demo07String {public static void main(String[] args) {//1.创建Scanner对象,键盘录入Scanner sc = new Scanner(System.in);//2.定义三个变量,用来统计int big = 0;int small = 0;int number = 0;//3.调用next方法录入一个字符串,遍历字符串,将每一个字符拿出来String data = sc.next();char[] chars = data.toCharArray();for (int i = 0; i < chars.length; i++) {char num = chars[i];/*4.统计大写字母A-Z -> 65-90比如:B -> 66 -> 在65-90之间,证明就是大写字母*/if (num>='A' && num<='Z'){big++;}/*5.统计小写字母a-z -> 97-122比如:b -> 98 -> 在97-122之间,证明就是小写字母*/if (num>='a' && num<='z'){small++;}/*6.统计数字:0-9 -> 48-57比如:字符1 -> 49 -> 在48-57之间,证明就是数字*/if (num>='0' && num<='9'){number++;}}//7.将统计结果打印出来System.out.println("大写有"+big+"个");System.out.println("小写有"+small+"个");System.out.println("数字有"+number+"个");}
}
知识点 | 核心内容 | 重点 |
string转换功能 | toCharArray:将字符串转成字符数组 | 区分toCharArray与getBytes方法 |
getBytes:将字符串转成byte数组,可指定编码 | 理解编码对字节数组长度的影响 | |
replace:替换字符串中的字符序列 | 区分replace的两个参数类型,理解其为CharSequence | |
字符判断与统计 | 判断字符是否为大写、小写或数字 | 理解ASCII码范围,并准确应用判断条件 |
统计字符串中大写字母、小写字母及数字的出现次数 | 遍历字符串,准确统计各类字符数量 | |
Scanner类应用 | 使用Scanner类从键盘录入字符串 | 理解Scanner类的next方法,获取输入字符串 |
字符遍历方法 | 使用toCharArray或for循环遍历字符串 | 掌握多种遍历字符串的方法,灵活应用 |
统计结果输出 | 将统计结果以特定格式输出 | 准确拼接并输出统计结果,注意格式规范 |
8..String分割方法
public class Demo08String {public static void main(String[] args) {String s = "abc,txt";String[] split = s.split(",");for (int i = 0; i < split.length; i++) {System.out.println(split[i]);}System.out.println("===============");String s2 = "haha.hehe";String[] split1 = s2.split("\\.");for (int i = 0; i < split1.length; i++) {System.out.println(split1[i]);}}
}
一些其他方法
1.boolean contains(String s) -> 判断老串儿中是否包含指定的串儿
2.boolean endsWith(String s) -> 判断老串儿是否以指定的串儿结尾
3.boolean startsWith(String s) -> 判断老串儿是否以指定的串儿开头
4.String toLowerCase()-> 将字母转成小写
5.String toUpperCase() -> 将字母转成大写
6.String trim() -> 去掉字符串两端空格public class Demo09String {public static void main(String[] args) {String s = "abcdefg";//1.boolean contains(String s) -> 判断老串儿中是否包含指定的串儿System.out.println(s.contains("a"));//2.boolean endsWith(String s) -> 判断老串儿是否以指定的串儿结尾System.out.println(s.endsWith("g"));//3.boolean startsWith(String s) -> 判断老串儿是否以指定的串儿开头System.out.println(s.startsWith("a"));//4.String toLowerCase()-> 将字母转成小写System.out.println("ADbcda".toLowerCase());//5.String toUpperCase() -> 将字母转成大写System.out.println("dafadRWERW".toUpperCase());//6.String trim() -> 去掉字符串两端空格System.out.println(" hadfhad hdsfha sfhdsh ".trim());System.out.println("==================");System.out.println(" hadfhad hdsfha sfhdsh ".replace(" ",""));}
}
知识点 | 核心内容 | 重点 |
字符串分割(split) | 按照指定规则分割字符串,参数为正则表达式 | 点(.)在正则中代表任意字符,需转义(\\\.)才能按字面点分割 |
字符串包含检测(contains) | 判断字符串是否包含指定子串 | 注意区分大小写 |
字符串首尾匹配(startsWith/endsWith) | 检测字符串是否以指定子串开头/结尾 | 可检测完整字符串但无实际意义 |
大小写转换(toLowerCase/toUpperCase) | 将字符串全部转为小写/大写 | 返回新字符串不改变原字符串 |
去空格(trim) | 去除字符串两端空格 | 无法去除字符串中间的空格 |
替换空格(replace) | 通过替换实现全部空格去除 | 比"先split再join"更高效 |
正则表达式特殊字符 | 点(.)代表任意字符 | 需用\\\转义特殊字符 |
9.StringBuilder
1.构造:StringBuilder()StringBuilder(String str) public class Demo01StringBuilder {public static void main(String[] args) {StringBuilder sb = new StringBuilder();System.out.println(sb);StringBuilder sb1 = new StringBuilder("abc");System.out.println(sb1);}
}
知识点 | 核心内容 | 重点 |
StringBuilder概述 | 可变字符序列,提供与StringBuffer兼容的API | 与StringBuffer方法相同但线程不安全 |
StringBuilder与String对比 | 拼接时不产生新对象,直接在缓冲区操作 | String拼接会产生新对象导致内存浪费 |
缓冲区机制 | 底层使用未被final修饰的byte数组(默认长度16) | 数组可修改 vs String的final数组 |
自动扩容规则 | 默认扩容:老数组2倍+2(16→34) | 特殊情况:当添加数据>默认扩容量时按实际需求扩容 |
性能优势 | 内存利用率高(减少对象创建) | 拼接效率显著高于String的"+"操作 |
源码分析 | 通过AbstractStringBuilder实现扩容(Arrays.copyOf) | 关键参数:coder/oldCapacity/newCapacity |
10.StringBuilder常用方法
常用方法:StringBuilder append(任意类型数据) -> 字符串拼接,返回的是StringBuilder自己StringBuilder reverse()-> 字符串翻转,返回的是StringBuilder自己String toString() -> 将StringBuilder转成String-> 用StringBuilder拼接字符串是为了效率,为了不占内存,那么拼完之后我们后续可能会对拼接好的字符串进行处理,就需要调用String中的方法,所以需要将StringBuilder转成String public class Demo02StringBuilder {public static void main(String[] args) {StringBuilder sb = new StringBuilder();StringBuilder sb1 = sb.append("张无忌");System.out.println(sb1);System.out.println(sb);System.out.println(sb==sb1);System.out.println("==============");//链式调用sb.append("赵敏").append("周芷若").append("小昭");System.out.println(sb);sb.reverse();System.out.println(sb);String s = sb.toString();System.out.println(s);}
}============================================================练习:键盘录入一个字符串,判断此字符串是否为"回文内容" 比如: abcba 上海自来水来自海上public class Demo03StringBuilder {public static void main(String[] args) {//1.创建Scanner对象Scanner sc = new Scanner(System.in);String data = sc.next();//2.创建StringBuilder对象StringBuilder sb = new StringBuilder(data);//3.翻转sb.reverse();//4.将StringBuilder转成StringString s = sb.toString();if (data.equals(s)){System.out.println("是回文内容");}else{System.out.println("不是回文内容");}}
}
知识点 | 核心内容 | 重点 |
Stream Builder的使用 | 创建对象(无参/有参构造) | 有参构造创建对象时缓冲区有内容 |
append方法(传任意类型数据) | append返回值是string builder对象,不会产生新对象 | |
链式调用 | 调方法后返回对象,可继续调其他方法 | |
reverse方法 | 字符串翻转,返回的还是原string builder对象 | |
toString方法 | 将string builder转成string,以便处理字符串 | |
回文内容判断 | 录入字符串,翻转后与原字符串比较 | 用equals方法比较内容 |
String与String Builder的区别 | String拼接字符串效率低,每次产生新对象 | |
String Builder拼接效率高,线程不安全 | 与String Buffer的区别在于线程安全和效率 | |
String Buffer拼接效率较低,但线程安全 |
11.数学相关类_Math类
public class Demo01Math {public static void main(String[] args) {//static int abs(int a) -> 求参数的绝对值System.out.println(Math.abs(-10));//static double ceil(double a) -> 向上取整System.out.println(Math.ceil(3.6));//static double floor(double a) ->向下取整System.out.println(Math.floor(3.6));//static long round(double a) -> 四舍五入System.out.println(Math.round(3.6));System.out.println(Math.round(-2.8));//static int max(int a, int b) ->求两个数之间的较大值System.out.println(Math.max(10,20));//static int min(int a, int b) ->求两个数之间的较小值System.out.println(Math.min(10,20));}
}
知识点 | 核心内容 | 重点 |
Math类概述 | 数学工具类,用于执行基本数学运算 | 构造方法私有化特点 |
Math类特点 | 1. 构造方法私有化; 2. 方法均为静态方法 | 工具类设计模式理解 |
绝对值计算 | Math.abs()方法使用,求绝对值 | 负数处理逻辑 |
取整方法 | Math.ceil()向上取整; Math.floor()向下取整; Math.round()四舍五入 | 负数取整规则 |
极值运算 | Math.max()求最大值; Math.min()求最小值 | 多值比较需嵌套调用 |
数学函数 | 包含指数/对数/平方根/三角函数等方法 | 实际应用场景理解 |
API文档特征 | 1. 无公开构造方法; 2. 直接显示字段摘要 | 与普通类的文档对比 |
12.数学相关类_BigInteger类
public class Demo02BigInteger {public static void main(String[] args) {BigInteger b1 = new BigInteger("121212121212121212121212121212121212121");BigInteger b2 = new BigInteger("121212121212121212121212121212121212121");//BigInteger add(BigInteger val) 返回其值为 (this + val) 的 BigIntegerSystem.out.println(b1.add(b2));//BigInteger subtract(BigInteger val) 返回其值为 (this - val) 的 BigIntegerSystem.out.println(b1.subtract(b2));//BigInteger multiply(BigInteger val) 返回其值为 (this * val) 的 BigIntegerSystem.out.println(b1.multiply(b2));//BigInteger divide(BigInteger val) 返回其值为 (this / val) 的 BigIntegerSystem.out.println(b1.divide(b2));}
}int intValue() 将BigInteger转成intlong longValue() 将BigInteger 转成 longBigInteger上限:42亿的21亿次方,内存根本扛不住,所以可以认为BigInteger无上限
知识点 | 核心内容 | 重点 |
BigInteger类概述 | 用于处理超大整数(超过long类型范围)的数据结构 | 与基本数据类型(如int/long)的存储上限差异 |
构造方法 | 必须通过字符串数字创建对象(如new BigInteger("123")) | 非数字字符串(如"ABC")会报错 |
四则运算方法 | add()加法、subtract()减法、multiply()乘法、divide()除法 | 方法命名与数学符号的对应关系(如subtract对应-) |
类型转换 | intValue()/longValue()将BigInteger转为基本数据类型 | 溢出风险(超大数转int可能丢失精度) |
理论上限 | 数值上限为42亿的20次方,但实际受内存限制 | 与long(2^63-1)的数值范围对比 |
13.数学相关类_BigDecimal类
常用方法:static BigDecimal valueOf(double val) -> 此方法初始化小数时可以传入double型数据BigDecimal add(BigDecimal val) 返回其值为 (this + val) 的 BigDecimalBigDecimal subtract(BigDecimal val) 返回其值为 (this - val) 的 BigDecimalBigDecimal multiply(BigDecimal val) 返回其值为 (this * val) 的 BigDecimalBigDecimal divide(BigDecimal val) 返回其值为 (this / val) 的 BigDecimal BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) divisor:除号后面的那个数scale:指定保留几位小数roundingMode:取舍方式static int ROUND_UP -> 向上加1static int ROUND_DOWN -> 直接舍去static int ROUND_HALF_UP -> 四舍五入如果除不尽,会报错,出现运算异常=======================================================================================## BigDecimal使用public class Demo03BigDecimal {public static void main(String[] args) {//big01();//big02();big03();}private static void big03() {BigDecimal b1 = new BigDecimal("3.55");BigDecimal b2 = new BigDecimal("2.12");BigDecimal divide = b1.divide(b2, 2, BigDecimal.ROUND_UP);System.out.println("divide = " + divide);double v = divide.doubleValue();System.out.println("v = " + v);}private static void big02() {BigDecimal b1 = new BigDecimal("3.55");//BigDecimal b2 = new BigDecimal("2.12");BigDecimal b2 = BigDecimal.valueOf(2.12);//BigDecimal add(BigDecimal val) 返回其值为 (this + val) 的 BigDecimalBigDecimal add = b1.add(b2);System.out.println("add = " + add);//BigDecimal subtract(BigDecimal val) 返回其值为 (this - val) 的 BigDecimalBigDecimal subtract = b1.subtract(b2);System.out.println("subtract = " + subtract);//BigDecimal multiply(BigDecimal val) 返回其值为 (this * val) 的 BigDecimalBigDecimal multiply = b1.multiply(b2);System.out.println("multiply = " + multiply);//BigDecimal divide(BigDecimal val) 返回其值为 (this / val) 的 BigDecimalBigDecimal divide = b1.divide(b2);System.out.println("divide = " + divide);}private static void big01() {float a = 3.55F;float b = 2.12F;float result = a-b;System.out.println("result = " + result);//1.4300001}
}double doubleValue() 将此BigDecimal转成double========================================================================================
## 3.BigDecimal除法过时方法解决1.注意:如果调用的成员上面有一个横线,证明此成员过时了,底层会有一个注解@Deprecated修饰,但是过时的成员还能使用,只不过被新的成员代替了,不推荐使用了2.方法:divide(BigDecimal divisor, int scale, RoundingMode roundingMode) divisor:代表除号后面的数据scale:保留几位小数roundingMode:取舍方式-> RoundingMode是一个枚举,里面的成员可以类名直接调用UP:向上加1 DOWN:直接舍去 HALF_UP:四舍五入 private static void big04() {BigDecimal b1 = new BigDecimal("3.55");BigDecimal b2 = new BigDecimal("2.12");BigDecimal divide = b1.divide(b2, 2, RoundingMode.HALF_UP);System.out.println("divide = " + divide);}
知识点 | 核心内容 | 重点 |
BigDecimal的作用 | 解决float/double直接运算的精度损失问题,尤其适用于金融计算 | 构造方法传参必须用String,禁用double(不可预知性) |
BigDecimal初始化 | 推荐构造方法new BigDecimal("3.55")或静态方法BigDecimal.valueOf(3.55) | valueOf支持double参数但内部仍转为String处理 |
加减乘除方法 | add()、subtract()、multiply()、divide() | 除法divide()需处理除不尽异常(如指定保留小数位和舍入模式) |
舍入模式 | ROUND_UP(向上加一)、ROUND_DOWN(直接舍去)、ROUND_HALF_UP(四舍五入) | 默认除法必须精确,否则抛ArithmeticException |
类型转换 | doubleValue()将BigDecimal转回double | 转换后可能重新引入精度问题,需谨慎使用 |
知识点 | 核心内容 | 重点 |
过时方法标识 | 方法名或输入方式带横杠表示已过时(@Deprecated注解标记) | 横杠的语义与底层注解关联性 |
过时方法的使用 | 仍可调用但不推荐,需替换为新方法 | 新旧方法兼容性差异 |
替代方案 | BigDecimal.divide()新版本使用RoundingMode枚举(如DOWN/UP/HALF_UP) | 参数类型从int变为枚举,功能等价但更规范 |
枚举类型应用 | RoundingMode包含舍入策略(如直接舍去、向上加一、四舍五入) | 枚举成员通过类名直接调用(如RoundingMode.DOWN) |
新旧方法对比 | 旧方法:divide(divisor, scale, int roundingMode); 新方法:divide(divisor, scale, **RoundingMode mode**) | 参数含义一致,但枚举类型提升代码可读性 |
14.日期相关类_Date类
构造:Date() -> 获取当前系统时间Date(long time) -> 获取指定时间,传递毫秒值 -> 从时间原点开始算 private static void date01() {//Date() -> 获取当前系统时间Date date1 = new Date();System.out.println("date1 = " + date1);//Date(long time) -> 获取指定时间,传递毫秒值 -> 从时间原点开始算Date date2 = new Date(1000L);System.out.println("date2 = " + date2);}====================================================================================常用方法:
1.void setTime(long time) -> 设置时间,传递毫秒值-> 从时间原点开始算
2.long getTime()->获取时间,返回毫秒值private static void date02() {Date date = new Date();//1.void setTime(long time) -> 设置时间,传递毫秒值-> 从时间原点开始算date.setTime(1000L);//2.long getTime()->获取时间,返回毫秒值System.out.println(date.getTime());}
知识点 | 核心内容 | 重点 |
Date类的定义 | Date类表示特定的一个瞬间,可以精确到毫秒 | Date类的精确度和表示的内容 |
时间原点 | Unix系统起始时间,1970年1月1日0时0分0秒(格林威治时间,零时区) | Unix时间原点的具体时间和含义 |
时区的概念 | 地球上不同位置的时间差异,北京位于东八区 | 时区的定义和北京所在的时区 |
时区与时间的关系 | 每个时区相差15度,时间相差1小时;北京时间比时间原点所在时区时间差8小时 | 时区之间的时间差异和计算方法 |
Date类的构造方法 | 无参构造方法获取当前系统时间; 有参构造方法传递毫秒值创建时间对象 | Date类两种构造方法的使用和区别 |
Date类的方法 | 常用方法:getTime()获取时间的毫秒值; setTime(long time)设置时间的毫秒值 | Date类常用方法的名称和功能 |