目录
String、StringBuilder、StringBuffer的比较(面试常问)
包装类
针对八种基本数据类型定义相应的引用类型——包装类
包装类和基本数据类型的转换(装箱和拆箱)
- jdk5以前的手动装箱和拆箱方式,装箱:基本类型->包装类型,拆箱反之
- jdk5以后的自动装箱和拆箱方式
- 自动装箱底层调用的是valueOf方法,比如Integer.valueOf()
package com.lili.wrapper;
public class Integer01 {
public static void main(String[] args) {
//int的装箱和拆箱
//jdk5前手动装箱和拆箱
//手动装箱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;
//自动装箱 int -> Integer
Integer integer2 = n2; //底层使用的是Integer.valueOf(n2)
//自动拆箱 Integer -> int
int n3 = integer2;
}
}
包装类练习
下面代码正确吗?
Double d = 100d; //①
Float f = 1.5f; //②
answer:
都正确
①自动装箱,底层:Double.valueOf(100d)
②自动装箱,底层:Float.valueOf(1.5f)
经典面试题⭐
以下两个输出一样吗?
haohaosikao~
//1
Object obj1 = true ? new Integer(1) : new Double(2.0);
System.out.println(obj1);
//2
Object obj2;
if(true) {
obj2 = new Integer(1);
}else {
obj2 = new Double(2.0);
}
System.out.println(obj2);
answer:
不一样
三元运算符是一个整体,int型的1会自动转换类型为最高精度double,变为1.0
所以输出结果是:
1.0
1
包装类型和String类型的相互转换
以Integer为例:
public class WrapperVSString {
public static void main(String[] args) {
Integer i = 100; //自动装箱
//包装类(Integer) -> String
//方式1
String str1 = i + "";
//方式2
String str2 = i.toString();
//方式3
String str3 = String.valueOf(i);
//String -> 包装类(Integer)
String str4 = "123";
//方式1
Integer integer = Integer.parseInt(str4);
//方式2
Integer integer1 = new Integer(str4);
}
}
Integer类和Character类的常用方法
Integer->右键Diagrams->Show Diagram可以看到Integer包装类的结构图
点击红色小圆圈m可以看到Integer的所有方法
package com.lili.wrapper;
public class WrapperMethod {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_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类面试题
1.看看下段代码会输出什么? (有点难度)⭐
public class WrapperExercise02 {
public static void main(String[] args) {
Integer integer = new Integer(1);
Integer integer1 = new Integer(1);
System.out.println(integer == integer1); //①
Integer m = 1;
Integer n = 1;
System.out.println(m == n); //②
Integer x = 128;
Integer y = 128;
System.out.println(x == y); //③
}
}
answer:
本题需要了解Integer的底层原理(查看源码)
alt + 7查看Integer的结构
或者点击左下角图标查看Integer的结构
Integer的valueOf()方法源码:
对于①,很简单,2个Integer对象都是new创建的,指向不同的地址,所以integer != integer1,输出false;
对于②,自动装箱,底层用的是Integer.valueOf(1),1在IntegerCache.low~IntegerCache.high(-128~127)之间,所以直接返回的是1,输出true;
对于②,自动装箱,底层Integer.valueOf(128),128不在IntegerCache.low~IntegerCache.high,
所以返回的是new Integer(128),输出false.
2. 5min思考以下代码输出什么?
package com.lili.wrapper;
public class WrapperExercise03 {
public static void main(String[] args) {
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //1
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4); //2
Integer i5 = 127;
Integer i6 = 127;
System.out.println(i5 == i6); //3
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8); //4
Integer i9 = 127;
Integer i10 = new Integer(127);
System.out.println(i9 == i10); //5
Integer i11 = 127;
int i12 = 127;
System.out.println(i11 == i12); //6
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14); //7
}
}
answer:
对于7和8,只要有基本数据类型,判断的就是值是否相等⭐
package com.lili.wrapper;
public class WrapperExercise03 {
public static void main(String[] args) {
System.out.print("1 ");
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //1 false
System.out.print("2 ");
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4); //2 false
System.out.print("3 ");
Integer i5 = 127;
Integer i6 = 127; //底层Integer.valueOf(127),127∈[-128,127],返回127
System.out.println(i5 == i6); //3 true
System.out.print("4 ");
Integer i7 = 128;
Integer i8 = 128; //底层Integer.valueOf(128),128不在[-128,127],返回new Integer(128)
System.out.println(i7 == i8); //4 false
System.out.print("5 ");
Integer i9 = 127; //Integer.valueOf(127)返回127
Integer i10 = new Integer(127);
System.out.println(i9 == i10); //5 false
System.out.print("6 ");
Integer i11 = 127;
int i12 = 127; //只要有基本数据类型,判断的就是值是否相等
System.out.println(i11 == i12); //6 true
System.out.print("7 ");
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14); //7 true
}
}
String类
- String对象用于保存字符串,即一组字符序列
- 字符串常量是用双引号“”包起的字符序列
- 字符串的字符使用Unicode编码,一个字符统一占2个字节
- String类是final类,不能被继承
- String类实现了 Serializable接口,String可以串行化(可以网络传输);String类实现了Comparable接口,String对象可以比较大小
- String类有很多构造器
String类有属性private final char value[],用于存放字符串内容,注意:value[]是final,不可以修改,这里的不能修改指的是value不能指向新的地址,而不是值不能修改!⭐⭐
两种创建String对象的区别
1. 直接赋值 String name = "kiddy";
先从常量池查看是否有"kiddy"空间,如果有,直接指向;如果没有则创建一个,再指向,name最终指向的是常量池的空间地址。
2. 调用构造器 String name2 = new String("kiki");
先在堆中创建空间,name2指向堆中创建的这个空间。堆中维护一个char[]类型的value属性,value指向常量池的一块空间,查看常量池是否有"kiki"空间,如果有,value直接指向;如果没有则创建一个,value指向。name2最终指向的是堆中的空间地址。
String小练习
1. 看看下面的代码会输出什么?
package com.lili.String_;
public class StringExercise01 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
}
}
answer:
true
true
字符串的equals方法判断的是值是否相等,
字符串1 == 字符串2 判断的是是否是一个对象。
s1 与 s2 都指向常量池的 "abc",是一个对象
再看一个:
2. 本题需要了解一下字符串的intern方法
intern():如果字符串常量池存在和当前字符串对象值相同的字符串对象(equals==true),那么返回字符串常量池里那个对象,如果不存在,把当前字符串对象存进常量池,,返回当前字符串对象,即最终返回的还是常量池中的对象
来看看下面这道题吧~
package com.lili.String_;
public class StringExercise03 {
public static void main(String[] args) {
String a = "haha";
String b = new String("haha");
System.out.println(a.equals(b));
System.out.println(a == b);
System.out.println(a == b.intern());
System.out.println(b == b.intern());
}
}
answer:
package com.lili.String_;
public class StringExercise03 {
public static void main(String[] args) {
String a = "haha";
String b = new String("haha");
System.out.println(a.equals(b)); //true
System.out.println(a == b); //false
System.out.println(a == b.intern()); //true
System.out.println(b == b.intern()); //false b指向的是堆中的对象,b.intern()指向的是常量池的对象
}
}
3. 看输出结果,并画出内存分布草图
package com.lili.String_;
public class StringExercise05 {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Kidy";
Person p2 = new Person();
p2.name = "Kidy";
System.out.println(p1.name.equals(p2.name));
System.out.println(p1.name == p2.name);
System.out.println(p1.name == "Kidy");
}
}
class Person{
public String name;
}
answer:
true true true
字符串的特性
1. String 是一个final类,代表不可变的字符序列,字符串对象一旦被分配,内容不可变
2. 再来看一道面试题
String a = "hello" + "abc"; 创建了几个对象?
answer:
创建了一个对象“helloabc”
编译器会进行优化--> String a = "helloabc";
3. 再变动一下看看
String a = "hello";
String b = "abc";
String c = a + b;
创建了几个对象?
answer:
创建了3个对象
4.下面代码输出什么?
package com.lili.String_;
public class StringExercise09 {
public static void main(String[] args) {
String s1 = "hi";
String s2 = "kiki";
String s5 = "hikiki";
String s6 = (s1 + s2).intern();
System.out.println(s5 == s6);
System.out.println(s5.equals(s6));
}
}
answer:
5. 这一题请好好想,思考思考输出什么
有点难度⭐
package com.lili.String_;
public class StringExercise10 {
public static void main(String[] args) {
Test t = new Test();
t.change(t.str, t.ch);
System.out.print(t.str + " and ");
System.out.println(t.ch);
}
}
class Test{
String str = new String("kiki");
final char[] ch = {'j', 'a', 'v', 'a'};
public void change(String str, char[] ch){
str = "java";
ch[0] = 'h';
}
}
answer:
String的常见方法
package com.lili.String_;
public class StringMethod01 {
public static void main(String[] args) {
String s1 = "aa & kiki";
String s2 = s1.replace("aa", "kuku");
System.out.println(s1); //aa & kiki replace替换的是返回值,s1字符串不变
System.out.println(s2); //kuku & kiki
}
}
String格式化输出
String info = String.format("名字是%s,年龄是%d", "kiki", 21);
StriingBuffer类
- StringBuffer的直接父类是AbstractStringBuilder
- StringBuffer实现了Serializable,StringBuffer对象可以串行化
- 父类AbstractStringBuilder中有属性 char[] value,且不是final的,该value数组存放字符串内容,引用存放在堆中
- StringBuffer是一个final类,不能被继承
String VS StringBuffer
String 保存的是字符串常量,里面的值不能修改,每次更新字符串实际是指向一个新的地址,效率较低 private final char[] value
String 保存的是字符串变量,里面的值可以修改,每次更新字符串不用每次更新地址(只要容量不够才更新),效率较高 char[] value(这个放在堆中)
StringBuffer构造器
package com.lili.StringBuffer_;
public class StringBuffer_ {
public static void main(String[] args) {
//1 创建一个大小为16的char[]
StringBuffer stringBuffer = new StringBuffer();
//2 通过构造器指定char[]的大小
StringBuffer stringBuffer1 = new StringBuffer(100);
//3 通过给一个String对象创建StringBuffer,char[]的大小就是字符串长度+16
StringBuffer stringBuffer2 = new StringBuffer("hello"); //len:21
}
}
StringBuffer与String相互转换
String -> StringBuffer:
1 StringBuffer构造器转换
2 StringBuffer的append方法
StringBuffer -> String:
1 调用StringBuffer的toString方法
2 调用String构造器
package com.lili.StringBuffer_;
public class StringAndStringBuffer {
public static void main(String[] args) {
//String -> StringBuffer
String str = "hello";
//1 StringBuffer构造器转换
StringBuffer stringBuffer = new StringBuffer(str);
//2 StringBuffer的append方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1.append(str);
//StringBuffer -> String
StringBuffer stringBuffer2 = new StringBuffer("kiki");
//1 调用StringBuffer的toString方法
String str1 = stringBuffer2.toString();
//2 调用String构造器
String str2 = new String(stringBuffer2);
}
}
StringBuffer常用方法
package com.lili.StringBuffer_;
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增
s.append(',');
s.append("java");
s.append(100).append(true).append(8.0);
System.out.println(s); //hello,java100true8.0
//删
//删除[10, 13)的内容
s.delete(10, 13);
System.out.println(s); //hello,javatrue8.0
//改
//替换[10, 14)的内容
s.replace(10, 14, "lulu");
System.out.println(s);
//查
//查找字符串第一次出现时的索引位置,找不到返回-1
int javaIndex = s.indexOf("java");
System.out.println("javaIndex: " + javaIndex);
//插
//在索引为6的位置插入内容,6之后的内容后移
s.insert(6, "study");
System.out.println(s);
//长度
System.out.println("长度:"+s.length());
}
}
StringBuffer练习
1. 看看每条语句是否有问题,看源码,看输出
public class StringBufferExercise01 {
public static void main(String[] args) {
String str = null; //ok
StringBuffer stringBuffer = new StringBuffer(); //ok
stringBuffer.append(str); //ok看源码,底层调用的是父类AbstractStringBuilder的appendNull()
System.out.println(stringBuffer.length()); //输出4
System.out.println(stringBuffer); //输出null
StringBuffer stringBuffer1 = new StringBuffer(str); //看源码,不ok,空指针异常
System.out.println(stringBuffer1); //
}
}
查看源码知:StringBuffer对象append一个空串,会添加"null"到value[]中 ,所以
stringBuffer.length() = 4;
StringBuffer构造器字符串参数为空时,空对象.length()会有空指针异常
2. 输入商品名称和商品价格,要求打印效果示例,要求:价格的小数点低位起每3位用逗号隔开
效果示例:
商品名 商品价格
手机 123,5.59
主要是解决价格格式化输出问题,将价格用字符串接收,转为StringBuffer类型,就可以用StringBuffer的insert方法插入","
package com.lili.StringBuffer_;
import java.util.Scanner;
public class StringBufferExercise02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("商品名:");
String name = scanner.next();
System.out.print("商品价格:");
String price = scanner.next(); //价格用字符串接收
StringBuffer s = new StringBuffer(price); //转为StringBuffer对象
for (int i = s.indexOf(".") - 3; i > 0; i -= 3) {
s = s.insert(i, ",");
}
System.out.println("商品名\t商品价格\n" + name + "\t" + s);
}
}
StringBuilder类
一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(即StringBuilder存在线程安全问题)。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单线程使用时,建议优先采用此类,因为在大多数实现中,比StringBuilder要快
1. StringBuilder继承了AbstractStringBuilder类
2. StringBuilder 实现了Serializable,StringBuilder 对象可以串行化(对象可以网络传输,可以保存到文件)
3. StringBuilder是final类,不能被继承
4. StringBuilder 对象字符序列仍存放在其父类的char[] value
5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized关键字,因此在单线程的情况下使用
String、StringBuilder、StringBuffer的比较(面试常问)
String:不可变字符序列,效率低,但是复用率高
StringBuffer:可变字符序列,效率较高,线程安全
StringBuilder:可变字符序列,效率最高,但线程不安全
如果多次执行改变字符串的操作,会导致大量副本字符串留在内存中,降低效率,
如String s = "a"; s += "b"; 原来的"a"不用了但还在内存中,s指向"ab"。
结论⭐:
- 如果字符串存在大量的修改,不要用String,一般用StringBuffer或StringBuilder
- 如果字符串存在大量的修改,单线程,使用StringBuilder
- 如果字符串存在大量的修改,多线程,使用StringBuilder
- 如果字符串很少修改,被多个对象引用,使用String,比如配置信息等
Math类
Math类常用方法(都是静态方法):
package com.lili.math_;
public class MathMethod {
public static void main(String[] args) {
//1 abs绝对值
System.out.println(Math.abs(-1));
//2 pow求幂
System.out.println(Math.pow(2, 3));
//3 ceil向上取整
System.out.println(Math.ceil(-1.1));
//4 floor向下取整
System.out.println(Math.floor(-1.1));
//5 round四舍五入
System.out.println(Math.round(7.6));
//6 sqrt求开方
System.out.println(Math.sqrt(64));
}
}
random()返回的是一个[0,1)的随机小数
思考:请写出获取a~b之间的一个随机整数,a,b均为整数,如[2,7]
int a = 2;
int b = 7;
//(int)(Math.random()*(b-a))得到的是[0,b-a)的整数
//(int)(Math.random()*(b-a+1))得到的是[0,b-a]的整数
for (int i = 0; i < 100; i++) {
System.out.println(a + (int) (Math.random() * (b - a + 1)));
}
Arrays类
Arrays里面包含了一系列静态方法,用于管理或操作数组
sort()
1 默认升序排序
Arrays.sort(integers);
2 sort重载的也可以通过传入一个接口Comparator实现定制排序,传入2个参数:待排序数组和实现了Comparator接口的匿名内部类,要求实现compare方法
package com.lili.arrays_;
import java.util.Arrays;
import java.util.Comparator;
public class ArraysMethod01 {
public static void main(String[] args) {
Integer[] integers = {9, -1, 80, 60, 8};
//Arrays.toString()显示数组
System.out.println(Arrays.toString(integers));
//1 默认升序排序
//Arrays.sort(integers);
//2 sort重载的也可以通过传入一个接口Comparator实现定制排序
// 传入2个参数:待排序数组和实现了Comparator接口的匿名内部类,
// 要求实现compare方法
Arrays.sort(integers, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println("===排序后===");
System.out.println(Arrays.toString(integers));
}
}
package com.lili.arrays_;
import java.util.Arrays;
import java.util.Comparator;
public class ArraysSortCustom {
public static void main(String[] args) {
int[] arr = {1, -1, 8, 0, 20};
//bubble01(arr);
bubble02(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return i1 - i2;
}
});
System.out.println(Arrays.toString(arr));
}
//冒泡排序
public static void bubble01(int[] arr){
int temp = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
//冒泡+定制
public static void bubble02(int[] arr, Comparator c){
int temp = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(c.compare(arr[j],arr[j+1]) > 0){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}
binarySearch()
通过二分搜索法进行查找,要求数组必须有序
如果数组中不存在该元素,就return -(low + 1);(low是找不到时二分查找算法里的左边界)
package com.lili.arrays_;
import java.util.Arrays;
public class ArraysMethod02 {
public static void main(String[] args) {
Integer[] arr = {1, 2, 16, 21, 120, 510};
//Arrays.binarySearch()通过二分搜索法进行查找,要求必须有序
int index = Arrays.binarySearch(arr, 1);
System.out.println(index);
}
}
copyOf()
数组元素的复制
1.从原数组中拷贝指定长度元素到新数组中
2.如果拷贝的长度大于原数组长度,就在新数组后面加null
3.如果拷贝的长度小于0,就抛出异常
package com.lili.arrays_;
import java.util.Arrays;
public class ArraysMethod02 {
public static void main(String[] args) {
//copyOf() 数组元素的复制
//1.从原数组中拷贝指定长度元素到新数组中
//2.如果拷贝的长度大于原数组长度,就在新数组后面加null
//3.如果拷贝的长度小于0,就抛出异常
Integer[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println("===拷贝得到的数组===");
System.out.println(Arrays.toString(newArr));
}
}
fill()
数组元素的填充
用指定值替换数组原有的所有元素
package com.lili.arrays_;
import java.util.Arrays;
public class ArraysMethod02 {
public static void main(String[] args) {
//fill()数组元素的填充
//用指定值替换数组原有的所有元素
Integer[] num = new Integer[]{9, 2, 3};
Arrays.fill(num, 88);
System.out.println("===填充后===");
System.out.println(Arrays.toString(num));
}
}
equals()
比较两个数组元素是否完全一致
如果arr1和arr2完全一样,就返回true,否则返回false
package com.lili.arrays_;
import java.util.Arrays;
public class ArraysMethod02 {
public static void main(String[] args) {
Integer[] arr1 = {1, 2, 8};
Integer[] arr2 = {1, 2, 8};
Integer[] arr3 = {1, 8};
System.out.println(Arrays.equals(arr1, arr2));
System.out.println(Arrays.equals(arr1, arr3));
}
}
asList()
将一组值转换为list
返回的asList的编译类型:List接口
返回的asList的运行类型:java.util.Arrays$ArrayList,是Arrays类的静态内部类
package com.lili.arrays_;
import java.util.Arrays;
import java.util.List;
public class ArraysMethod02 {
public static void main(String[] args) {
//asList()
//将一组值转换为list
//返回的asList的编译类型:List接口
//返回的asList的运行类型:java.util.Arrays$ArrayList,是Arrays类的静态内部类
List asList = Arrays.asList(2,3,4,9,0,6);
System.out.println("asList = " + asList);
System.out.println("asList运行类型:" + asList.getClass());
}
}
Arrays类练习
自定义Book类,包含name和price,分别按price降序排序,按name长度升序排序。要求使用定制排序。
package com.lili.arrays_;
import java.util.Arrays;
import java.util.Comparator;
public class ArraysExercise {
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("青年文摘", 5);
books[3] = new Book("挑战程序设计竞赛", 51);
//按书的价格降序
System.out.println("===按书的价格降序===");
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o2.getPrice() - o1.getPrice();
}
});
System.out.println(Arrays.toString(books));
// for (Book book: books){
// System.out.println(book);
// }
//按书名长度升序
System.out.println("===按书名长度升序===");
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o1.getName().length() - o2.getName().length();
}
});
System.out.println(Arrays.toString(books));
}
}
class Book{
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return name + " " + price;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
}
System类
System类常用方法
exit()
exit(0)退出当前程序,
0 表示正常状态
package com.lili.system_;
public class System_ {
public static void main(String[] args) {
System.out.println("ok1...");
System.exit(0);
System.out.println("ok2...");
}
}
arraycopy()
拷贝数组
5个参数
@param1 src 源数组
@param2 srcPos 原数组拷贝起始索引
@param3 dest 目标数组
@param4 destPos 目标数组拷贝索引
@param5 length 拷贝长度
package com.lili.system_;
import java.util.Arrays;
public class System_ {
public static void main(String[] args) {
int[] arr = {12, 8, 1};
int[] destArr = new int[6];
System.arraycopy(arr, 0, destArr, 1, 2);
//System.arraycopy(arr, 0, destArr, 0, arr.length);
System.out.println(Arrays.toString(destArr));
}
}
currentTimeMillis()
返回当前时间距离1970-1-1的毫秒数
package com.lili.system_;
import java.util.Arrays;
public class System_ {
public static void main(String[] args) {
//currentTimeMillis()返回当前时间距离1970-1-1的毫秒数
System.out.println(System.currentTimeMillis());
}
}
BigInteger类和BigDecimal类
- BigInteger适合保存比较大的整型;
- BigDecimal适合保存精度很高的浮点型
1. 在对BigInteger进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
package com.lili.bignum;
import java.math.BigInteger;
public class BigInteger_ {
public static void main(String[] args) {
BigInteger bigInteger = new BigInteger("1234566666666666666699999");
System.out.println(bigInteger);
BigInteger bigInteger1 = new BigInteger("5234526666666666666699999");
//1 在对BigInteger进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
System.out.println("+:" + bigInteger.add(bigInteger1));
System.out.println("-:" + bigInteger1.subtract(bigInteger));
System.out.println("*:" + bigInteger.multiply(bigInteger1));
System.out.println("/:" + bigInteger1.divide(bigInteger));
}
}
对BigDecimal进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
除运算可能抛出ArithmeticException异常(除不尽)
解决办法:在调用divide()时,指定精度即可
如果有无限循环小数,就会保留分子的精度
package com.lili.bignum;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimal_ {
public static void main(String[] args) {
BigDecimal bigDecimal = new BigDecimal("3.14159266666666666666888888");
System.out.println(bigDecimal);
BigDecimal bigDecimal1 = new BigDecimal("3");
//对BigDecimal进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
System.out.println("+:" + bigDecimal.add(bigDecimal));
System.out.println("-:" + bigDecimal.subtract(bigDecimal1));
System.out.println("*:" + bigDecimal.multiply(bigDecimal1));
//除运算可能抛出ArithmeticException异常
//解决办法:在调用divide()时,指定精度即可
//如果除不尽(有无限循环小数,就会保留分子的精度)
//System.out.println("/:" + bigDecimal.divide(bigDecimal1));
System.out.println("/:" + bigDecimal.divide(bigDecimal1, BigDecimal.ROUND_CEILING));
}
}
Date类
1. Date()创建的对象:获取当前系统时间 (Date是java.util包下的)
2. Date(long date):通过指定毫秒数得到时间
3. 默认是国外日期输出格式
package com.lili.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Date01 {
public static void main(String[] args) throws ParseException {
//1.Date()获取当前系统时间,这里的Date是java.util包下的
Date date = new Date();
System.out.println(date);
//2.Date(long date)通过指定毫秒数得到时间
Date date1 = new Date(2222240000000l);
System.out.println(date1);
//3.默认是国外日期输出格式
}
}
SimpleDateFormat日期格式类
指定日期输出格式
可以把格式化的字符串转成Date,把String->Date,使用parse()方法;
字符串格式需和SimpleDateFormat对象一致,否则抛出ParseException异常;
需在方法声明处throws ParseException
package com.lili.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Date01 {
public static void main(String[] args) throws ParseException {
Date date = new Date();
//可以创建SimpleDateFormat对象,指定日期输出格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
System.out.println(sdf.format(date));
//5.可以把格式化的字符串转成Date
// 在把String->Date时,使用parse()方法,
// 字符串格式需和SimpleDateFormat对象一致,否则抛出ParseException异常
// 需在方法声明处throws ParseException
String str = "2024年06月30日 09:47:33 星期日";
Date date2 = sdf.parse(str);
System.out.println(sdf.format(date2));
}
}
Calendar类(日历)
第二代日期类
1. Calendar是一个抽象类,并且Calendar构造器是私有的
2. 可以通过getInstance()获取实例
3. Calendar提供大量的方法和字段
4. Calendar没有提供相应的格式化类,需要程序员自己组合
package com.lili.date;
import java.util.Calendar;
public class Calendar_ {
public static void main(String[] args) {
//1.获取日历对象
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
//2.获取日历对象的某个字段
System.out.println("年:" + calendar.get(Calendar.YEAR));
//Calendar.MONTH是从0开始编号的,所以需要加1
System.out.println("月:" + (calendar.get(Calendar.MONTH) + 1));
System.out.println("日:" + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分:" + calendar.get(Calendar.MINUTE));
System.out.println("秒:" + calendar.get(Calendar.SECOND));
System.out.println(calendar.get(Calendar.YEAR) + "年"+
(calendar.get(Calendar.MONTH) + 1) +"月" +
calendar.get(Calendar.DAY_OF_MONTH) + "日 " +
calendar.get(Calendar.HOUR_OF_DAY) + ":" +
calendar.get(Calendar.MINUTE) + ":" +
calendar.get(Calendar.SECOND));
}
}
第三代日期类
第三代日期常见方法
LocalDate只得到日期
LocalTime只得到时间
LocalDateTime得到日期和时间
package com.lili.date;
import java.time.LocalDateTime;
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
System.out.println("年:"+now.getYear());
System.out.println("月:"+now.getMonth()); //月份英文
System.out.println("月:"+now.getMonthValue()); //月份数
System.out.println("日:"+now.getDayOfMonth());
System.out.println("时:"+now.getHour());
System.out.println("分:"+now.getMinute());
System.out.println("秒:"+now.getSecond());
}
}
DateTimeFormatter格式日期类
package com.lili.date;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class LocalDate_ {
public static void main(String[] args) {
//第三代日期
//1.LocalDateTime得到日期和时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//2.DateTimeFormatter格式化日期
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
System.out.println(dtf.format(now));
}
}
plus和minus方法
对当前时间进行加或减
package com.lili.date;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class LocalDate_ {
public static void main(String[] args) {
//第三代日期
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
//LocalDateTime提供plus和minus方法对当前时间进行加或减
LocalDateTime localDateTime = now.plusHours(1);
System.out.println(dtf.format(localDateTime));
}
}
Instant时间戳
类似于Date
提供了一系列和Date类转换的方法
Instant->Date
通过Date的静态方法from可以把Instant转为Date
Date->Instant
通过Date对象的toInstant可以把Date转为Instant
package com.lili.date;
import java.time.Instant;
import java.util.Date;
public class Instant_ {
public static void main(String[] args) {
//1.通过Instant的静态方法now()获取表示当前时间戳的对象
Instant now = Instant.now();
System.out.println(now);
//2.通过Date的静态方法from可以把Instant转为Date
Date date = Date.from(now);
//3.通过Date对象的toInstant可以把Date转为Instant
Instant instant = date.toInstant();
}
}
练习题
1. 对字符串指定部分进行反转,public static String reverse(String str, int start, int end);
要求:异常处理
package com.lili.homework;
public class Homework01 {
public static void main(String[] args) {
String str = "hello,java";
System.out.println("===翻转前===");
System.out.println(str);
try {
str = reverse(str, 6, str.length()-1);
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
System.out.println("===翻转后===");
System.out.println(str);
}
public static String reverse(String str, int start, int end) {
if(!(str!=null && start > 0 && start < end && end <str.length())){
throw new RuntimeException("参数不正确!");
}
char[] s = str.toCharArray();
char temp = ' ';
for (int i = start, j = end; i < j; i++, j--) {
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
return new String(s);
}
}
2.
本人解法:
package com.lili.homework;
import java.util.Scanner;
public class Homework02 {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String userName = "";
String passWord = "";
String email = "";
System.out.print("请输入2~4长度的用户名:");
try {
userName = setUserName();
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
System.out.print("请输入6位纯数字密码:");
try {
passWord = setPassWord();
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
System.out.print("邮箱:");
try {
email = setEmail();
System.out.println("注册成功!");
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
}
public static String setUserName() {
String userName = scanner.next();
int len = userName.length();
if (!(len >= 2 && len <= 4)) {
throw new RuntimeException("用户名长度应为2~4!");
}
return userName;
}
public static String setPassWord() {
String passWord = scanner.next();
if (!(passWord.length() == 6)) {
throw new RuntimeException("密码应为6位!");
}
try {
Integer pwd = Integer.parseInt(passWord);
} catch (NumberFormatException e) {
throw new RuntimeException("密码应由纯数字组成!");
}
return passWord;
}
public static String setEmail() {
String email = scanner.next();
int i = email.indexOf('@');
int j = email.indexOf('.');
if (!(i > -1 && i < j)) {
throw new RuntimeException("邮箱输入有误,应包含@和.且@在.前!");
}
return email;
}
}
3. 字符串内存分配问题,看看输出
package com.lili.homework;
public class Homework05 {
public static void main(String[] args) {
String s1 = "yuanyuan";
Animal a = new Animal(s1);
Animal b = new Animal(s1);
System.out.println(a == b); //false
System.out.println(a.equals(b)); //false
System.out.println(a.name == b.name); //true
String s4 = new String("yuanyuan");
String s5 = "yuanyuan";
System.out.println(s1 == s4); //false s1指向常量池,s4指向堆
System.out.println(s4 == s5); //false
String t1 = "hello" + s1;
String t2 = "helloyuanyuan";
System.out.println(t1.intern() == t2); //true
}
}
class Animal{
String name;
public Animal(String name) {
this.name = name;
}
}