JAVA常用类(包装类 String类 StringBuffer类…)
在开发的过程中我们会使用各种各样的类,下面我们来看一看这些类吧
1.包装类:wrapper
- 包装类的分类:
- 针对八种基本数据类型的引用类型——包装类
- 有了类的特点就可以调用类中的方法
这些类的继承关系图:
装箱和拆箱
装箱顾名思义就是将物品装进箱子里在这里就是将基本数据类型变换为包装类
拆箱就是将包装类转变成基本数据类型
- jdk5前采用手动装箱和拆箱,装箱:基本类型->包装类型,拆箱反之
- jdk5以后采用自动装箱和插箱
- 自动装箱底层调用的是valueOf方法,比如integer.valueOf()
public class Integer {
public static void main(String[] args) {
//int-->Integer 的装箱和拆箱
//手动装箱
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱Integer-->int
int i = integer.intValue();
//jdk5后,自动装箱拆箱
//自动装箱
int n2 = 200;
Integer integer2 = n2;//底层使用的是Integer.valueOf(n2);
//自动拆箱
int n3 = integer2;//底层使用的是integer.intValue();方法
}
}
经典面试题:
Object obj1 = true?new Integer(1):new Double(2.0);//三元运算符是一个整体
System.out.println(obj1);
//会输出1.0
1.0
包装类常用方法
- 包装类和string类的相互转换
public static void main(String[] args) {
//包装类(Integer)->String
Integer i = 100;
//方式一
String str1 = i+"";//此方式并没有将i转换为string,而是新生成了一个对象赋给了str1
//方式二
String str2 = i.toString();
//方式三
String str3 = String.valueOf(i);
//String ->包装类(Integer)
//方式一
String str4 = "12345";
Integer i1 = Integer.parseInt(str4);
//方式二
Integer integer = new Integer(str4);
}
2.Integer和Character常用方法(需要的时候可以去查,不需要记住所有的方法)
System.out.println(Integer.MIN_VALUE); //返回最小值
System.out.println(Integer.MAX_VALUE);//返回最大值
System.out.println(Character.isDigit('a'));//判断是不是数字
System.out.println(Character.isLetter('a'));//判断是不是字母
System.out.println(Character.isUpperCase('a'));//判断是不是大写
System.out.println(Character.isLowerCase('a'));//判断是不是小写
System.out.println(Character.isWhitespace('a'));//判断是不是空格
System.out.println(Character.toUpperCase('a'));//转成大写
System.out.println(Character.toLowerCase('A'));//转成小写
Integer创建机制
public static void method(){
Integer i =new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j);//判断是否为同一个对象 False
//源码:
// public static Integer valueOf(int i) {
// if (i >= IntegerCache.low && i <= IntegerCache.high)
// return IntegerCache.cache[i + (-IntegerCache.low)];
// return new Integer(i);
// }low=-128,high=127
Integer m =1;//底层Integer.valueOf(1);在-128—127之间在缓存数组中返回
Integer n = 1;//底层Integer.valueOf(1);
System.out.println(m==n);
Integer x = 128;//底层Integer.valueOf(128)要new
Integer y = 128;
System.out.println(x==y);
}
2.String类
我们来看一下源码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
- String对象用于保存字符串,也就是一组字符序列
- 字符串常量对象是用双引号括起来的字符序列如:“你好”,“122.3”,“boy”
- 字符串字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
- String类常用构造器
- String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int count)
String s5 = new String(byte[] b);
- String s1 = new String();
- string 类实现了接口 serializable string可以串行化,数据可以在网络传输
- string 类实现了接口comparable string对象可以比较大小
- string是个final类,不能被其他的类继承,每次更新都需要重新开辟空间。
- string 有属性 private final char value[];用于存放字符串内容
- valule是一个final类型不可修改(地址不可修改):value不能指向新的地址,但是单个字符内容是可以变化的
final char[] value = {'a','b','c'};
char[] v2 = {'t','o','m'};
value[0] = 'H';
//value = v2;不可修改value的地址
- 两种创建string对象的区别
String s = "cgx";
String s2 = new String("cgx");
方法一在常量池中创建一个地址
方法二在堆中new一个地址,他首先在堆里面开辟一个空间,然后在常量池中搜寻如果常量池中有且相等则使用常量池中的值没有的话就在常量池中创建一个新的字符串常量
//小测试
String a = "abc";
String b = "abc";
System.out.println(a.equals(b));//判断ab的值是否相同
System.out.println(a==b);//判断ab是否指向同一个地址
//小测试
String a = "abc";
String b =new String("abc");
System.out.println(a.equals(b));//判断a b的值是否相同
System.out.println(a==b);//判断a b是否指向同一个地址
//当调用intern方法时,如果池已经包含与equals(Object)方法确定的相当于此String对象的字符串,则返回来自池的字符串。
// 否则,此String对象将添加到池中,并返回对此String对象的引用。
//由此可见,对于任何两个字符串s和t , s.intern() == t.intern()是true当且仅当s.equals(t)是true
//b.intern(返回常量池的地址)
System.out.println(a==b.intern());
System.out.println(b==b.intern());
true
false
true
false
//小测试
//以下语句创建了几个对象,画出内存布局图
String s1 = "hello";
s1 = "haha"
//两个
//小测试
//以下语句创建了几个对象,画出内存布局图
String a = "hello" + "abc"//编译器会优化,等价于String a = "helloabc";
//只有一个对象
//编译器不傻,做一个优化,判断创建的常量池对象是否有引用指向,若有则创建没有则优化
//小测试
//以下语句创建了几个对象,画出内存布局图
public static void main(String[] args) {
String a ="hello";
String b = "abc";
//1.先创建一个StringBuilder sb = StringBuilder();
//2.执行sb.append("hello")
//3.执行sb.append("abc")
// 4.String s = sb.toString()
//最后其实是c指向堆中的对象(String) value[]->池中"helloabc";
String c = a+b;//不同于String a = "hello" + "abc"
}
//三个对象
//小测试
public class StringExercise10 {
public static void main(String[] args) {
}
}
class Test1 {
String str = new String("hsp");
final char[] ch = {'j', 'a', 'v', 'a'};
public void change(String str, char ch[]) {
str = "java";
ch[0] = 'h';
}
public static void main(String[] args) {
Test1 ex = new Test1();
ex.change(ex.str, ex.ch);
System.out.print(ex.str + " and ");
System.out.println(ex.ch);
}
}
String常用方法
public static void main(String[] args) {
//1. euqals 判断字符串是否相同不区分大小写
String str1 = "hello";
String str2 = "Hello";
System.out.println(str1.equals(str2));false
//2.equalsIgnoreCase判断字符串是否相同区分大小写
System.out.println(str1.equalsIgnoreCase(str2));true
//3.length 获取字符串的个数,字符串长度
System.out.println("程冠希".length());3
//4.indexOf 获取字符在字符串对象中第一次出现的索引,索引从0开始,找不到返回-1
String s1 = "wer@erwre@ad";
int index = s1.indexOf('@');
System.out.println(index);3
//5.获取字符在字符串对象中最后一次出现的索引,索引从0开始,找不到返回-1
int index2 = s1.lastIndexOf('@');
System.out.println(index2);9
//6.substring截取指定范围的子串
String name = "hello,张三";
System.out.println(name.substring(6));//截取6后面所有的内容 张三
System.out.println(name.substring(0,5));//从索引0开始截取,截取到第5-1个字符 hello
}
System.out.println(name.substring(2,5));//llo
public static void main(String[] args) {
//1.toUpperCase转换成大写
String s = "hello";
System.out.println(s.toUpperCase());//HELLO
//2.toLowerCase转换成小写
System.out.println(s.toLowerCase());//hello
//3.contact拼接字符串
String s1 = "1";
s1 = s1.concat("2").concat("3").concat("4");
System.out.println(s1);
//4.替换字符串中的字符
String s2 = "宝玉 and 林黛玉 林黛玉 林黛玉";
s2 = s2.replace("林黛玉","薛宝钗");
//5.split 分割字符串,对某些分割字符 我们需要转义比如 | \\ 等
String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
String[] split = poem.split(",");
System.out.println("====分割后内容====");
for (int i = 0;i<split.length;i++){
System.out.println(split[i]);
}
//6.toCharArray 转为字符数组
char[] chs = s.toCharArray();
for (int i = 0;i<s.length();i++){
System.out.println(chs[i]);
}
//7.format 格式化字符串
String name = "程冠希";
int age = 18;
double score = 100;
char sex = '男';
String formatStr = "我的姓名是%s 年龄是%d,成绩是%.2f, 性别是%c,希望大家喜欢我!";
String info = String.format(formatStr,name,age,score,sex);
System.out.println(info);
//8.compareTo比较字符串的大小,长度相同则比较字符的ASCII值的大小从首位开始比
String s3 = "bbc";
String s4 = "abc";
System.out.println(s3.compareTo(s4));
}
3.StringBuffer类
我们来先看一下源码:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
由此我们看出StringBuffer的一些特点
- StringBuffer是一个final类,不能被继承
- 实现了Serializable接口,即StringBuffer对象可以实现串行化
- StringBuffer类继承了AbstractStringBuilder类所以StringBuffer里面有父类的属性char[] value;该value数组存放字符串内容,引出存放在堆中的
- StringBuffer字符内容是存在 char[] value中的 ,所以每次在修改字符内容时不需要更改字符串的地址,既不需要新建一个字符串对象,所以效率高于String
那么String和StringBuffer又有什么区别呢❓
String类保存的是字符串常量,所以里面的值不能更改,但我们可以更改地址来更新对象的引用,效率较低
StringBuffer类保存的是字符串变量,所以里面的值可以更改,每次更新实际上值更新了 char[] value里面的内容在常量池中不存在该变量
那么String和Stringbuffer如何相互转换呢❓
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("hello");
System.out.println(stringBuffer);
//String->StringBuffer
String str = "hello tom";
//方式一 使用构造器 对str没有影响返回一个新的对象
StringBuffer stringBuffer1 = new StringBuffer(str);
//方式二 使用 append 方法
StringBuffer stringBuffer2 = new StringBuffer();
stringBuffer2.append(str);
//StringBuffer->String
StringBuffer stringBuffer3 = new StringBuffer("程冠希爱学习");
//方式一 使用StringBuffer提供的toString方法
String s = stringBuffer3.toString();
//方式二 使用构造器
String s1 =new String(stringBuffer3);
}
知道了StringBuffer的特点和string的区别,我们来看一看StringBuffer的常用方法:
StringBuffer常用方法:
其常用方法可以概括为增删改查
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增
s.append(',');
s.append("张三");
s.append("李四").append("王五").append(100).append(true).append(10.5);
System.out.println(s);
//删
s.delete(6,10);//删除[6,10)的字符
System.out.println(s);
//改
s.replace(6,9,"程冠希");//更改[6,9)的内容
System.out.println(s);
//查 查找第一次出现的索引,找不到返回-1
int index = s.indexOf("00");
System.out.println(index);//9
//插
s.insert(9,"爱学习");//在9的位置插入,后面的往后移
System.out.println(s);
System.out.println(s.length());
}
下面我们来看几道小测验:
public static void main(String[] args) {
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str);// super.append(str);调用 private AbstractStringBuilder appendNull()方法
System.out.println(sb.length());
System.out.println(sb);
//抛出空指针NullPointerException异常
StringBuffer sb1 = new StringBuffer(str);//super(str.length() + 16); 空没有长度会抛出空指针异常
System.out.println(sb1);
}
4
null
Exception in thread "main" java.lang.NullPointerException
/*
输入商品名称和商品价格,要求打印效果示例, 使用前面学习的方法完成:
商品名 商品价格
手机 123,564.59 //比如 价格 3,456,789.88
要求:价格的小数点前面每三位用逗号隔开, 在输出。
*/
public static void main(String[] args) {
System.out.print("请输入商品价格:");
Scanner scanner = new Scanner(System.in);
String s=scanner.next();
StringBuffer s1 = new StringBuffer(s);
//找到小数点的索引,然后在前三位插入,即可
for(int i = s1.indexOf(".")-3;i>0;i-=3){
s1 = s1.insert(i,",");
}
//int i = s1.indexOf(".");
// while(i>0){
// s1 = s1.insert(i,",");
// i=i-3;
// }
System.out.println(s1);
}
4.StringBuilder类
我们来看源码:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
我们可以看出StringBuilder与StringBuffer一样都继承了 AbstractStringBuilder类 实现了Serializable接口
实现了Serializable接口,即StringBuffer对象可以实现串行化
StringBuilder类继承了AbstractStringBuilder类所以StringBuffer里面有父类的属性char[] value;该value数组存放字符串内容,引出存放在堆中的
StringBuilder字符内容是存在 char[] value中的 ,所以每次在修改字符内容时不需要更改字符串的地址,既不需要新建一个字符串对象,所以效率高于String
那么StringBuilder字符串又有什么特点呢❓
- StringBuilder是一个可变的字符序列。此类提供了一个与StringBuffer兼容的API但不保证同步(StringBuilder 不是线程安全)。该类被设计用作StringBuffer的一个简易替换,当字符缓冲区被单个线程使用的时候使用.如果可能优先采取该类,因为该类的速度较快
- 在StringBuilder上的主要操作是 append 和 insert方法 ,可以重载这些方法,以接收任意类型的数据。
- StringBuilder的方法没有做互斥的处理,即没有synchronize关键字,因此在单线程的情况下使用StringBuilder
下面我们来看一看String StringBuffer和StringBuilder的比较
StringBuilder和StringBuffer非常类似,均可代表字符序列,且方法一样
String: 不可变字符序列,效率低,但复用率高
StringBuffer:可变字符序列,效率较高,线程安全
StringBuilder:可变字符序列,效率最高,线程不安全
String使用注意:string s = “a”;//创建了一个字符串"a"
s + =“b”;//又新生成了一个对象"ab"
如果多次执行这些操作会导致内存中有大量的副本对象,降低效率,所以,如果我们对String做大量的修改就不使用String
不同情况下使用String StringBuffer 和StringBuilder
- 如果存在大量的修改操作,一般使用StringBuffer 或 StringBuilder
- 如果存在大量的修改操作,并且在单线程的情况下,使用StringBuilder
- 如果存在大量的修改操作,并且在多线程的情况下,使用StringBuffer
- 如果很少修改,并且被多个对象调用,使用String
5.Math类
Math类中包含用于执行基本数学运算的方法,比如初等指数,对数,平方根和三角函数等
public class MathMethod {
public static void main(String[] args) {
//看看 Math 常用的方法(静态方法)
//1.abs 绝对值
int abs = Math.abs(-9);
System.out.println(abs);//9
//2.pow 求幂
double pow = Math.pow(2, 4);//2 的 4 次方
System.out.println(pow);//16
//3.ceil 向上取整,返回>=该参数的最小整数(转成 double);
double ceil = Math.ceil(3.9);
System.out.println(ceil);//4.0
//4.floor 向下取整,返回<=该参数的最大整数(转成 double)
double floor = Math.floor(4.001);
System.out.println(floor);//4.0
//5.round 四舍五入 Math.floor(该参数+0.5)
long round = Math.round(5.51);
System.out.println(round);//6
//6.sqrt 求开方
double sqrt = Math.sqrt(9.0);
System.out.println(sqrt);//3.0
//7.random 求随机数
// random 返回的是 0 <= x < 1 之间的一个随机小数
// 思考:请写出获取 a-b 之间的一个随机整数,a,b 均为整数 ,比如 a = 2, b=7
// 即返回一个数 x 2 <= x <= 7
// 老韩解读 Math.random() * (b-a) 返回的就是 0 <= 数 <= b-a
// (1) (int)(a) <= x <= (int)(a + Math.random() * (b-a +1) )
// (2) 使用具体的数给小伙伴介绍 a = 2 b = 7
// (int)(a + Math.random() * (b-a +1) ) = (int)( 2 + Math.random()*6)
// Math.random()*6 返回的是 0 <= x < 6 小数
// 2 + Math.random()*6 返回的就是 2<= x < 8 小数
// (int)(2 + Math.random()*6) = 2 <= x <= 7
// (3) 公式就是 (int)(a + Math.random() * (b-a +1) )
for(int i = 0; i < 100; i++) {
System.out.println((int)(2 + Math.random() * (7 - 2 + 1)));
}
//max , min 返回最大值和最小值
int min = Math.min(1, 9);
int max = Math.max(45, 90);
System.out.println("min=" + min);
System.out.println("max=" + max);
}
6.Arrays类
//Arrays里面包含了一系列静态方法,用于管理或操作数组
Integer[] integer ={1,20,90,30};
System.out.println(Arrays.toString(integer));//遍历数组
//sort方法,排序
//因为数组为引用类型,所以通过sort排序后会直接影响到实参 arr
Integer arr[] = {30,-20,2,31,90};
Arrays.sort(arr);//默认排序
System.out.println(Arrays.toString(arr));
//通过传入一个接口Comparator实现定制排序
//实现了Comparator接口的匿名内部类,要求实现compare方法
/*程序最终会执行到binarySort
private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c) {
while (left < right) {
int mid = (left + right) >>> 1;
if (c.compare(pivot, a[mid]) < 0)//这里调用我们自己写的compare方法
right = mid;
else
left = mid + 1;
}*/
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1,Object o2) {
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return i2 - i1;
}
});
System.out.println("====排序后====");
System.out.println(Arrays.toString(arr));
[1, 20, 90, 30]
[-20, 2, 30, 31, 90]
====排序后====
[90, 31, 30, 2, -20]
以上的Comparator实现了接口编程的思想我们来自己写一个排序
public static void main(String[] args) {
int[] arr = {1, -1, 8, 9, 20};
bubble01(arr);
System.out.println(Arrays.toString(arr));
bubble02(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer)o1;
int i2 = (Integer)o2;
return i2-i1;
}
});
System.out.println(Arrays.toString(arr));
}
//使用冒泡排序实现
public static void bubble01(int[] arr3) {
int temp = 0;
for (int i = 0; i < arr3.length - 1; i++) {
for (int j = 0; j < arr3.length - 1 - i; j++) {
//从小到大
if (arr3[j] > arr3[j + 1]) {
temp = arr3[j];
arr3[j] = arr3[j + 1];
arr3[j + 1] = temp;
}
}
}
}
//使用接口编程通过传入一个接口Comparator实现定制排序
//冒泡加定制
public static void bubble02(int[] arr3, Comparator c) {
int temp = 0;
for (int i = 0; i < arr3.length - 1; i++) {
for (int j = 0; j < arr3.length - 1 - i; j++) {
//从小到大
if (c.compare(arr3[j],arr3[j+1])>0) {//这里调用自己写的compare方法从而实现定制排序,动态绑定机制
temp = arr3[j];
arr3[j] = arr3[j + 1];
arr3[j + 1] = temp;
}
}
}
}
[-1, 1, 8, 9, 20]
[20, 9, 8, 1, -1]
Arrays其他的一些常用方法
Integer[] arr = {1,2,90,123,567};
//1.binarySearch 通过二分搜索法进行查找,要求必须排好序
//如果数组中不存在该元素,就返回 return-(low+1);low就是没找到值的左边值的下标
int index = Arrays.binarySearch(arr,567);
System.out.println("index="+index);
//2.copyOf数组元素的复制
//从arr数组中拷贝arr.length个元素到newArr数组中
//如果拷贝长度>arr.length就在新数组后面添加null
//如果拷贝长度<0就抛出异常NegativeArraySizeException
//该方法底层使用的是System.arraycopyOf(arr,arr.length)
Integer[] newArr = Arrays.copyOf(arr,5);
System.out.println("=====拷贝完毕后====");
System.out.println(Arrays.toString(newArr));
//3.fill数组元素的填充,填充为全部替换
Integer[] num = new Integer[]{9,3,2};
Arrays.fill(num,99);
System.out.println("num数组填充后");//[99, 99, 99]
System.out.println(Arrays.toString(num));
//4.equals 比较两个数组的元素内容是否一致
//如果一致返回true不一致则返回false
Integer[] arr2 ={1,2,90,30};
boolean equals = Arrays.equals(arr,arr2);
System.out.println("equals="+equals);
//5.asList 将一组值转为list
//1.asList方法,会将(2,3,4,5,6,1,2)转换为一个list集合
//返回的 asList 编译类型 List(接口)下面的List是一个接口
//asList的运行类型 class java.util.Arrays$ArrayList
//private static class ArrayList<E> extends AbstractList<E>
// implements RandomAccess, java.io.Serializable
List asList = Arrays.asList(2,3,4,5,6,1,2);
System.out.println("asLis="+asList);
System.out.println("asList的运行类型"+asList.getClass());
小测验
案例:自定义 Book 类,里面包含 name 和 price,按 price 排序(从大到小)。
要求使用两种方式排序 , 有一个 Book[] books = 4 本书对象. 使用前面学习过的传递 实现 Comparator 接口匿名内部类,也称为定制排序。
[同学们完成这个即可 10min ], 可以按照 price (1)从大到小 (2)从小到大 (3) 按照书名长度从大到小
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("青年文摘 20 年", 5);
books[3] = new Book("java 从入门到放弃~", 300);
//1.price从大到小排
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = (Book)o1;
Book book2 = (Book)o2;
double pricVal = book2.getPrice()-book1.getPrice();
if (pricVal>0){
return 1;
}else if(pricVal<0){
return -1;
}else {
return 0;
}
}
});
System.out.println(Arrays.toString(books));
//从小到大排
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = (Book)o1;
Book book2 = (Book)o2;
double pricVal = book1.getPrice()-book2.getPrice();
if (pricVal>0){
return 1;
}else if(pricVal<0){
return -1;
}else {
return 0;
}
}
});
System.out.println(Arrays.toString(books));
//按照书名长度从大到小
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = (Book)o1;
Book book2 = (Book)o2;
int lenValue = book1.getName().length()-book2.getName().length();
if (lenValue>0){
return 1;
}else if(lenValue<0){
return -1;
}else {
return 0;
}
}
});
System.out.println(Arrays.toString(books));
}
//Book类
public class Book{
private String name;
private double price;
public Book(String name,double price){
this.name = name;
this.price = price;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public double getPrice(){
return price;
}
public void setPrice(double price){
this.price = price;
}
@Override
public String toString() {
return "Book{"+
"name="+name+'\\'+
",price=" + price +
'}' ;
}
}
7.System类
System类常见方法和案例
public static void main(String[] args) {
//1.exit(0)表示程序退出
//0表示一个状态,正常的状态
System.out.println("ok1");
//System.exit(0);
System.out.println("ok2");
//2.arraycopy:复制元素数组,比较适合底层调用,一般使用Arrays.copyOf完成复制数组
int[] src = {1,2,3};
int[] dest = new int[3];//当前是{0,0,0}
System.arraycopy(src,//源数组
0,//从源数组的哪个位置开始拷贝
dest,//目的数组
0,//把源数组的数据拷贝到目标数组的哪个索引
src.length);//拷贝的长度
System.out.println(Arrays.toString(dest));
//3.currentTimeMillis返回当前时间距离1970-1-1的毫秒数
System.out.println(System.currentTimeMillis());
}
8.BigInteger和BigDecimal类
//BigInter适合保存比较大的整型
//BigDecimal适合保存精度比较大的浮点型
//常用方法:加减乘除
//当需要处理很大的整数时,long不够用
//使用BigInteger来搞定
//long l = 237888888888888888888888888888888888888;
BigInteger bigInteger = new BigInteger("237888888888888888888888888888888888888");
BigInteger bigInteger1 = new BigInteger("1111111111111111111111111111111111");
System.out.println(bigInteger);
//在对BigInteger进行加减乘除的时候,需要使用相对应的方法,不能直接进行加减乘除
//可以创建一个 要操作的BigInteger 然后进行操作
//加
BigInteger add = bigInteger.add(bigInteger1);
System.out.println(add);
//减
BigInteger subtract = bigInteger.subtract(bigInteger1);
System.out.println(subtract);
//乘
BigInteger multiply = bigInteger.multiply(bigInteger1);
System.out.println(multiply);
//除
BigInteger divide = bigInteger.divide(bigInteger1);
System.out.println(divide);
//当我们需要保存一个精度很高的数时,double不够用
//可以使用BigDecimal
double d = 123.99999999999999999999999;
System.out.println(d);
BigDecimal bigDecimal = new BigDecimal("123.99999999999999999999991");
BigDecimal bigDecimal1 = new BigDecimal("3");
System.out.println(bigDecimal);
//对BigDecimal进行运算需要使用对应的方法
//创建一个需要操作的BigDecimal 然后调用方法即可
System.out.println(bigDecimal.add(bigDecimal1));
System.out.println(bigDecimal.subtract(bigDecimal1));
System.out.println(bigDecimal.multiply(bigDecimal1));
//System.out.println(bigDecimal.divide(bigDecimal1));无限循环小数会报错ArithmeticException
//在调用divide方法时,指定精度即可BigDecimal.ROUND_CEILING
//如果有无限循环小数,就会保留分子精度
System.out.println(bigDecimal.divide(bigDecimal1,BigDecimal.ROUND_CEILING));
9.日期类
第一代日期类
public static void main(String[] args) throws ParseException {
//1.获取当前系统时间
//2.这里Date类是在java.util包里面
//3.默认输出的日期是国外的方式,因此通常需要将格式进行转换
Date d1 = new Date();
System.out.println("当前日期="+d1);
Date d2 = new Date(9234567);//通过指定毫秒数得到时间
System.out.println("d2="+d2);//通过某个时间对应的毫秒数
//1.创建 SimpleDateFormat 对象,可以指定相应的格式
//2.这里格式的字母是规定好的,不能乱写
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = simpleDateFormat.format(d1);//将日期转换为指定格式字符串
System.out.println("当前日期="+format);
//1.可以把一个格式化的String转换为对应的Date
//2.得到Date仍在输出时,还是按照国外的形式,如果希望指定格式输出,需要转换
//3.在把String->Date时,使用的格式需要和给的String格式一样,否则会抛出转换异常ParseException
String s = "1966年01月01日 星期一 10:20:30";
Date parse = simpleDateFormat.parse(s);
System.out.println("parse="+simpleDateFormat.format(parse));
第二代日期类
先看一下Calendar的源码:
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
我们可以看出Calendar是一个抽象类,他为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
public static void main(String[] args) {
Calendar instance = Calendar.getInstance();//创建日历对象
System.out.println("instance="+instance);
//获取日历对象的某个日历字段
System.out.println("年:"+instance.get(Calendar.YEAR));
//月是从0开始编号的
System.out.println("月:"+(instance.get(Calendar.MONTH)+1));
System.out.println("日:"+instance.get(Calendar.DAY_OF_MONTH));
System.out.println("时:"+instance.get(Calendar.HOUR));
System.out.println("分:"+instance.get(Calendar.MINUTE));
System.out.println("秒:"+instance.get(Calendar.SECOND));
//Calendar没有转没得格式化方法,所以需要程序员自己来组合显示
System.out.println(instance.get(Calendar.YEAR) + "-" +
(instance.get(Calendar.MONTH)+1) + "-" +
instance.get(Calendar.DAY_OF_MONTH)+ " "+
instance.get(Calendar.HOUR_OF_DAY)+ ":"+
instance.get(Calendar.MINUTE) + ":" +
instance.get(Calendar.SECOND));
}
第三代日期类
由于前两代日期类均有不足
- 可变性:像日期和时间这样的类应该是不可变的。
- 偏移性:Date中的年份是从1900开始的,月份是从0开始的
- 格式化:格式化只对Date有用,对Calendar没用
- 他们不是线程安全的;不能处理闰秒等(每隔两天,多出1s)
public static void main(String[] args) {
//1.使用now()返回当前日期时间的对象
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
LocalDate now1 = LocalDate.now();//返回年月日
System.out.println(now1);
LocalTime now2 = LocalTime.now();//返回时间
System.out.println(now2);
//2.使用DateTimeFormatter对象来格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormatter.format(now);
System.out.println(format);//输出格式化后的时间
System.out.println("年:"+now.getYear());
System.out.println("月"+now.getMonth());
System.out.println("日"+now.getDayOfMonth());
System.out.println("时"+now.getHour());
System.out.println("分"+now.getMinute());
System.out.println("秒"+now.getSecond());
//提供plus和minus方法可以对当前时间进行加减
LocalDateTime localDateTime = now.plusDays(890);
System.out.println("890天后 "+dateTimeFormatter.format(localDateTime));
LocalDateTime localDateTime1 = now.minusMinutes(6666);
System.out.println("6666分钟前 "+dateTimeFormatter.format(localDateTime1));
}
System.out.println(now1);
LocalTime now2 = LocalTime.now();//返回时间
System.out.println(now2);
//2.使用DateTimeFormatter对象来格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormatter.format(now);
System.out.println(format);//输出格式化后的时间
System.out.println("年:"+now.getYear());
System.out.println("月"+now.getMonth());
System.out.println("日"+now.getDayOfMonth());
System.out.println("时"+now.getHour());
System.out.println("分"+now.getMinute());
System.out.println("秒"+now.getSecond());
//提供plus和minus方法可以对当前时间进行加减
LocalDateTime localDateTime = now.plusDays(890);
System.out.println("890天后 "+dateTimeFormatter.format(localDateTime));
LocalDateTime localDateTime1 = now.minusMinutes(6666);
System.out.println("6666分钟前 "+dateTimeFormatter.format(localDateTime1));
}