参考:https://www.bilibili.com/video/BV1Cv411372m?p=126&vd_source=7ceb7ef632bd249b5aacf41c00b5ea12
文章目录
Random
- Random生成随机数需要几步?
- 导包:importjava.util.Random;
- Random r = new Random();
- int number = r.nextint(10)
如何生成 65-91之间的随机数?
- 65-91=>(0-26)+65
- int number = r.nextint(27)+ 65;
String
- 构造
- String s = “小黑”
- 调用String类的构造器初始化字符串对象。
- 常用方法
String不可变性
- String对象的内容不可改变,被称为不可变字符串对象。
PS:
通过运算符得到的字符串对象不在字符串常量池中,而是在堆内存中创建一个对象(类似于new)。而且每进行一次运算,都会创建一个新的对象(编译优化除外,见案例2)
-
只要是以“…”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份;
-
但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。
案例
Java存在编译优化机制,程序在编译时:“a”+“b”+“c”会直接转成“abc”,以提高程序的执行性能。
ArrayList<>
集合
从集合中遍历元素,并筛选出元素删除它,应该如何操作才能不出bug?
- 方式一:每次删除一个数据后,索引-1。
- 方式二:从集合后面遍历然后删除,可以避免漏掉元素。
Object类
toString方法
- 功能:将对象转换为字符串
- 常用:子类重写toString方法,用来打印类中具体内容(IDE可自动生成)
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
equals(Object o)方法
- 功能:判断两个对象地址是否相等
- 常用: 子类重写,用来比较两个对象内容是否相等(IDE可自动生成)
public boolean equals(Object o) {
//1.判断两对象地址是否一样
if (this == o) return true;
/*
2.
先判断o是否为null
比较this和o的类型是否一样 ps:getClass()返回对象类型
*/
if (o == null || getClass() != o.getClass()) return false;
/*
比较成员对象
*/
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
clone()方法
- 功能:复制一个一摸一样的新对象返回
注意:
- Object类的clone方法被protected修饰,所以不能直接中使用。需要在子类中重写clone方法(IDE可自动生成)
- 需要实现Cloneable()接口(Cloneable:标记接口)
- 默认返回Object类型对象,因此在调用此方法时,需要进行强转。
浅克隆
- 拷贝出来的新对象,与原对象的数据一摸一样 (引用类型拷贝的只是地址)
深克隆
- 对象中基本数据类型直接拷贝
- 对象中的字符串类型拷贝的还是地址
- 对象中还包含其他对象,不会拷贝地址,会创建新对象
public class Test(){
public static void main(String[] args) throws CloneNotSupportedException {
A a1 = new A();
A a2 = (A) a1.clone();
}
}
public class A implements Cloneable{
private int num;
private String name;
private double[] scores;
//浅克隆
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//深克隆
@Override
protected Object clone() throws CloneNotSupportedException {
A a2 = (A) super.clone();
a2.scores = a2.scores.clone();
return a2;
}
}
Objects类
- 是一个工具类,提供了很多操作对象的静态方法。
equals(object a, object b)方法
- 先判断非空,再比较两个对象。
- 相比Object类的equals方法,Objects的equals既安全又准确。
public static void main(String[] args) {
String s1 = "lx";
String s2 = "lx";
System.out.println(s1.equals(s2)); //String类重写了equals方法,用来比较内容
/*
第二种为主流;
因为调用equals方法的类为null时,Object类的equals方法会报错
*/
System.out.println(Objects.equals(s1, s2));
}
isNull(object obj)方法
- 判断一个对象是null,为null返回true,反之为false。
notNull(object obj)方法
- 判断一个对象不是null,不为null返回true,反之为false。
包装类
Integer
- 自动装箱
- 自动拆箱
public static void main(String[] args){
// Integer a1 = new Integer(12); //已过时
Integer a2 = Integer.valueof(12);
//自动装箱
Integer a3 = 12;
//自动拆箱
int a4 = a3;
ArrayList<Integer> list = new ArrayList<>();
list.add(12); //自动装箱
int i = list.get(0); //自动拆箱
}
toString方法
- 把基本类型的数据装换位字符串
public static void main(String[] args){
Integer a = 23;
String s1 = Integer.toString(a); //"23"
System.out.println(s + 1); //"231"
String s2 = a.toString(); //"23"
System.out.println(s + 1); //"231"
String s3 = a + ""; //"23"
System.out.println(s + 1); //"231"
}
parseInt(String s)方法
- 把字符串类型的数值准换为基本类型
- 常用:int i =Integer.valueof(ageStr)
public static void main(String[] args){
String ageStr = "29";
int ageInt = Integer.parseInt(ageStr); //29
System.out.println(ageInt + 1); //30
//常用:
int ageInt_2 = Integer.valueof(ageStr); //30 ,自动拆箱
String scoreStr = "99.5";
double scoreD = Double.parseDouble(scoreStr); //99.5
System.out.println(scoreD + 0.5); //100.0
//常用:
double scoreD_2 = Double.valueof(scoreStr); //99.5 ,自动拆箱
}
StringBuilder类
- 可变字符串对象,相当于一个容器。它里面的字符串是可以改变的,是用来操作字符串的。
- 好处:更适合做字符串操作,效率更高,代码也更简洁。
- 若字符串操作较少,或不需要操作字符串,以及定义字符串变量,还是建议用String
StringBuilder()&StringBulider(String str)
- 构造器
public static void main(String[] args) {
StringBuilder s = new StringBuilder(); //""
StringBuilder s2 = new StringBuilder("lx"); //"lx"
}
append方法
- 拼接内容
public static void main(String[] args) {
s.append(12);
s.append("lanzhou");
s.append(true);
System.out.println(s); //重写了toString方法
/*链式编程
因为s.append()方法的返回值为s对象本身
*/
s.append("lx").append(99.5);
}
reverse方法
- 字符串反转
public static void main(String[] args) {
StringBuilder s = new StringBuilder("lx");
System.out.println(s.reverse()); //"xl"
}
length()方法
- 返回字符串长度
toString()方法
- 把StringBuilder对象有转换成String类型
String str = new StringBuilder("lx").toString();
StringBuffer类
- StringBuffer类的用法和StringBuilder是一模一样的
- 但StringBuffer是线程安全的,StringBuilder线程不安全
StringJoiner类
- 相比于StringBuilder,StringJoiner在某些场景下(如某些拼接场景)更简洁。
public static void main(String[] args) {
StringJoiner s = new StringJoiner(",");
s.add("java1");
s.add("java2");
s.add("java3");
System.out.println(s); //java1,java2,java3
StringJoiner s2 = new StringJoiner(",", "[", "]");
s2.add("java1");
s2.add("java2");
s2.add("java3");
System.out.println(s2); //[java1,java2,java3]
}
PS:
add方法只能接收String对象作为参数。
Math
- 常用方法
public static void main(String[] args){
double rm = Math.random(); // [0.0,1.0)
}
System
- 常用方法
public static void main(String[] args){
// static=0: 表示异常终止
System.exit(0); //终止虚拟机
}
public static void main(String[] args){
/*
截取系统时间。
返回值是long类型的时间毫秒值,指的是从1970-1-1 0:0:0开始走到此刻的总的毫秒值,1s=1000ms
*/
long time = System.currentTimeMills();
System.out.println(time);
}
Runtime
- 代表java程序所在的运行环境
- Rutime是一个单例类
public static void main(String[] args){
Runtime r = Runtime.getRuntime(); //单例类
}
- 常用方法
public static void main(String[] args){
Runtime r = Runtime.getRuntime(); //单例
类
long B = r.totalMemory(); //返回的是字节数
long KB = B/1024.0; //1KB = 1024B
r.exec("程序地址");
Process P = r.exec("QQ"); //因为QQ启动程序已经配置在环境变量中
Tread.sleep(5000); // 暂停5s
P.destory(); //销毁!关闭程序
}
BigDecimal
- 用于解决浮点型预算时,出现结果失真的问题
- 常用方法:
public static void main(String[] args){
double a = 0.1;
double b = 0.2;
double c = a + b; //有时为0.3000000004
BigDecimal a1 = new BigDecimal(Double.toString(a)); //方法一
BigDecimal b1 = BigDecimal.valueOf(b); // 方法二 推荐!
BigDecimal i = BigDecimal.valueOf(0.1);
BigDecimal j = BigDecimal.valueOf(0.3);
BigDecimal k = i.divide(j, 2, Round.HALF_UP); // 第二个参数为小数点后精度,第三个参数为飘上
double rs = k.doubleValue(); //BigDecimal转double
}
JDK8之前传统的日期、时间
Date
- 代表日期、时间
public static void main(String[] args){
Date d = new Date();
System.out.println(d);
//转毫米值
long time = d.getTime();
//把时间毫秒值转换成日期对象
//2s后时间是多少
time = time + 2*1000
Date d2 = new Date(time);
//直接把日期对象的时间进行修改
Date d3 = new Date();
d3.setTime(time); //d3 == d2
}
SimpleDateFormat
- 代表简单日期格式化,可以把日期对象、时间毫秒值格式化成我们想要的形式
- 常用方法:
public static void main(String[] args){
Date d = new Date();
System.out.println(d);
//转毫米值
long time = d.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE a");
String rs = sdf.format(d);
String rs2 = sdf.format(time); //rs == rs2
}
- 字符串时间解析成日期对象
public static void main(String[] args){
String dataStr = "2024-3-28 12:12:11";
//指定的时间格式必须与被解析时间格式一样
SImpleDateFormat sdf2 = new SimpleDateFoemat("yyyy-MM-dd HH:mm:ss")
}
Date d2 = sdf2.parse(dateStr);
Calender
为什么要学习Calender?
-
代表系统此刻的时间对应的日历。
-
通过它可以单独获取、修改时间中的年、月、日、时、分、秒等。
-
抽象类
-
常用方法:
public static void main(String[] args){
Calender now = Calender.getInstance();
System.out.println(now);
//获取日历中的某个信息
int year = now.get(Calender.YEAR);
int days = now.get(Calender.DAY_OF_YEAR);
Date d = now.getTime();
long time = now.getTimeMills();
now.set(Calender.MONTH, 9); //Calender中月份是从0开始记录的,so要+1
now.add(Calender.DAY_OF_YEAR, 100);
System.out.println(now);
JDK8开始新增的日期、时间
- JDK8新增的时间
- 对比老方法
LocalDate、LocalTime、LocalDataTime
- LocalDate:代表本地日期(年、月、日、星期)
- LocalTime:代表本地时间(时、分、秒、纳秒)
- LocalDataTime:代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒)
- 常用方法:
public static void main(String[] args){
LocalDate ld = LocalDate.now(); //不可变对象
System.out.println(ld);
//获取日期对象某个信息
int year = ld.getYear();
int month = ld.getMonthValue(); //1-12
int day = ld.getDayOfMonth();
int dayOfYear = ld.getDayOfYear();
int dayOfWeek = id.getDayOfWeek().getValue();
//修改某个信息(不可并对象)
LocalDate ld2 = ld.withYear(2099);
LocalDate ld3 = ld.withMonth(12);
LocalDate ld4 = ld.withDayOfMonth(19);
LocalDate ld5 = ld.withDayOfYear(205);
//把某个信息加多少
LocalDate ld6 = ld.plusYears(2);
LocalDate ld7 = ld.plusMonths(2);
LocalDate ld8 = ld.plusDays(2);
LocalDate ld9 = ld.plusWeeks(2);
//把某个信息减多少
LocalDate ld6 = ld.minusYears(2);
LocalDate ld7 = ld.minusMonths(2);
LocalDate ld8 = ld.minusDays(2);
LocalDate ld9 = ld.minusWeeks(2);
// 指定日期得到LocalDate对象
LocalDate ld10 = LocalDate.of(2099,12,12);
//判断2个日期对象是否相等、在前还是在后
System.out.println(ld8.equals(ld7));
System.out.println(ld8.isAfter(ld7));
System.out.println(ld8.isBefore(ld7));
}
public static void main(String[] args){
LocalTime lt = LocalTime.now(); //不可变对象
System.out.println(lt);
//获取日期对象某个信息
int hour = lt.getHour();
int minute = lt.getMinute();
int second = lt.getSecond();
int nano = lt.getNano(); //纳秒
//修改某个信息(不可并对象)
LocalTime lt2 = lt.withHour(10);
LocalTime lt3 = lt.withMinute(10);
LocalTime lt4 = lt.withSecond(10);
LocalTime lt5 = lt.withNano(10);
//把某个信息加多少
LocalTime lt6 = lt.plusHours(10);
LocalTime lt7 = lt.plusMinutes(10);
LocalTime lt8 = lt.plusSeconds(10);
LocalTime ld9 = ld.plusNanos(10);
//把某个信息减多少
LocalTime lt6 = lt.miusHours(10);
LocalTime lt7 = lt.minusMinutes(10);
LocalTime lt8 = lt.minusSeconds(10);
LocalTime ld9 = ld.minusNanos(10);
// 指定日期得到LocalDate对象
LocalTime ld10 = LocalTime.of(12,12,12);
//判断2个日期对象是否相等、在前还是在后
System.out.println(ld8.equals(ld7));
System.out.println(ld8.isAfter(ld7));
System.out.println(ld8.isBefore(ld7));
}
public static void main(String[] args){
LocalDateTime ldt = LocalDateTime.now(); //不可变对象
System.out.println(ldt);
//转LocalDate、LocalTime对象
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
//合并
LocalDateTime ldt2 = LocalDateTime.of(ld,lt);
ZoneId、ZoneDateTime
- 获取时区,创建带时区的时间对象
Instant
- 获取某个时间戳,该时间由两部分组成:从1970-01-0100:00:00开始走到此刻的总秒数+不够1秒的纳秒数
- 常用方法:
- 作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点
DateTimeFormatter
- 常用方法
public static void main(String[] args){
DataTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")
LocalDateTime now = LocalDateTime.now();
//方法一
String rs = formatter.format(now)
//方法二
String rs2 = now.format(formatter);
//解析时间,一般使用LocalDateTime提供的解析方法来解析
String dateStr = "2024年12月12时 12:12:11";
LocalDateTime ldt = LocalDateTime.parse(dateStr. formatter);
}
Period、 Duration
- Period(一段时期):计算两个LocalDate对象相差年数、月数、天数。
- Duration(持续时间):可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间
Arrays
- 用来操作数组的工具类
- 常用方法:
public static void main(String[] args){
int[] arr = {10,20,30,40,50};
System.out.println(Arrays.toString(arr));
int[] arr2 = Arrays.copyOfRange(arr, 1, 4); //包前不包后
//数组扩容
int[] arr3 = Array.copyOf(arr, 10); //用默认值填补
// setall方法,把数组原数据改为新数据在2存进去
double prices = {99.8,128,100};
Arrays.setAll(prices, new IntDoubleFunction(){
@override
public double applyAsDouble(int value){
//value = 0 1 2
return prices[value] * 0.8; // 价格打八折
}
});
//排序,默认升序
Arrays.sort(prices);
}
为对象排序
- 比较规则
- 方法一:
Public class Student implement Comparable<Student>{
pubilc int age;
@override
public int compareTo(Student o){
/*
升序:
左>右 返回正整数
左=右 返回0
左<右 返回负整数
降序:
左>右 返回负整数
左=右 返回0
左<右 返回正整数
理解:返回正数,左右交换。
所以,若升序排序,左大于右时,返回正整数;降序排序,左大于右时,要返回负整数。
*/
if(this.age > o.age){
return 1;
}else if(this.age < o.age){
return -1;
}else{
return 0;
}
}
// return this.age - o.age; 升序
// return o.age - this.age; 降序
}
- 方法二:
public static void main(String[] args){
Arrays.sort(students, new Comparator<Student>(){
@override
public int compare(Student o1, Student o2){
//指定比较规则,降序
if(o1.height > o2.height){
return -1;
}else if(o1.height < o2,height){
return 1;
}else return 0;
// return Double.compare(o1.height, o2.height); 升序
// return Double.compare(o2.height, o1.height); 升序
}
});
}