本周学习内容目录
一,面向对象高级三
1.成员内部类
- 创建对象的格式:外部类名.内部类名 对象名 = new 外部类().new 内部类();
Outer.Inner in = new Outer().new Inner();
- 当外部类和内部类中某一个变量名相同时,如何访问到不同的类变量?
public class Outer {
private int age = 99;
public static String a;
public class Inner{
private int age = 88;
private String name;
public void test(){
System.out.println(age);
System.out.println(a);
int age = 66;
System.out.println(age);// 66
System.out.println(this.age); // 88
System.out.println(Outer.this.age);// 99
}
2.静态内部类
- 概述:有static修饰的内部类,属于外部类自己特有
- 创建对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner in = new Outer.Inner();
- 静态内部类的特点:可以直接访问外部类的静态对象,不可以直接访问外部类的实例对象
3.匿名内部类
-
概述:就是一种特殊的局部内部类;所谓匿名:指的是程序员不需要为这个类声明名字
-
new 类或接口(参数值){
类体(一般是方法重写);
};
public class Test {
public static void main(String[] args) {
// 目标:掌握匿名内部类并使用
//1.把这个匿名内部类编译成一个子类,然后会立即创建一个子类对象出来
Animal a = new Animal(){
@Override
public void cry() {
System.out.println("猫喵喵的叫--");
}
};
a.cry();
}
}
abstract class Animal{
public abstract void cry();
}
- 特点:匿名内部类本质就是一个子类,并会立即创建出一个子类对象
- 作用:用于更方便的创建一个子类对象
4.枚举
- 注意:枚举的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象
- 枚举类的构造器都是私有的,因此,枚举类不能对外创建对象
- 枚举类都是最终类,不能被继承
- 枚举类中,从第二行开始,可以定义类的其他各种成员变量
- 编辑器为枚举类新增了几个方法,并且枚举类都是继承:Java.lang.Enum类的,从enum类也会继承到一些方法
// 3.枚举类提供一个一些额外的api
A[] as = A.values();
A a3 = A.valueOf("Y");
System.out.println(a3.name());
System.out.println(a3.ordinal());
5.泛型
- 认识泛型:
ArrayList<E> list1 = new ArrayList<>();
- 泛型方法的定义和使用
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 目标:掌握泛型方法的定义和使用
String rs = test("java");
System.out.println(rs);
Dog d = test(new Dog());
System.out.println(d);
// 需求:所有的汽车可以一起参加比赛
ArrayList<Car> cars = new ArrayList<>();
cars.add(new BMW());
cars.add(new BENZ());
go(cars);
ArrayList<BMW> bmws = new ArrayList<>();
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
ArrayList<BENZ> benzs = new ArrayList<>();
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
}
// 通配符,在使用泛型的时候可以代表一切类型 ?extends Car(上限) ?super Car(下限)
public static void go(ArrayList<? extends Car>cars){
}
public static <T> T test (T t){
return t;
}
}
class Dog{}
class Car{}
class BMW extends Car{}
class BENZ extends Car{}
-
泛型的注意事项
-
泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这是泛型擦除
-
泛型不支持基本数据类型,只能支持对象类型9引用数据类型)
二.常见API(一)
1.Object类
-
toString方法
基本作用:返回对象的字符串形式
存在的意义:让子类重写,以便返回子类的内容 -
equals方法
基本作用:默认是比较两个对象的地址是否一样
存在的意义:让子类重写,以便用于比较对象的内容是否相同
3.clone方法
- 要有Cloneable这个标志接口
public class User implements Cloneable{
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
2.Objects类
- 先判断空指针,在比较两个对象
System.out.println(Objects.equals(s1,s2));
源码分析
public static boolean equals(Object a,Object b){
return (a == b) || (a != null && a.equals(b));
}
- 判断对象是否为null。为null返回true,反之返回false
String s1 = null;
String s2 = "itheima";
System.out.println(Objects.isNull(s1));// true
System.out.println(Objects.isNull(s2));// false
- 判断对象是否不是null
String s1 = null;
String s2 = "itheima";
System.out.println(Objects.nonNull(s2));// true
System.out.println(Objects.nonNull(s1));// false
3.包装类
1.包装类
Java语言是一个面向对象的语言,但是Java中的基本数据类型确实不面向对象的。基本类型的数据不具备”对象“的特性(没有成员变量和成员方法可以调用),因此,Java为每种数据类型分别设计了对应的类,即包装类
(1)所有包装类都是final类型,因此不能创建他们的子类
(2)包装类是不可变类,一个包装类的对象自创建后,他所包含的基本类型数据就不能被改变
2.Integer类
自动装箱:可以自动把基本数据类型的数据变成包装类对象
Integer a3 = 13;
System.out.println(a3);
自动拆箱:可以自动把包装类型的对象转换成对应的基本数据类型
int a4 = a3;
System.out.println(a4);
- 把基本数据类型的数据转换成字符串
方法一:
Integer a = 23;
String rs1 = Integer.toString(a);// "23"
System.out.println(rs1 + 1);// 231
方法二:
String rs2 = a.toString();
System.out.println(rs2 + 1);// 231
方法三:
String rs3 = a + "";
System.out.println(rs3 + 1);// 231
- 把字符串类型的数据转换成对应的基本数据类型
String ageStr = "29";
// int age = Integer.parseInt(ageStr);
int age = Integer.valueOf(ageStr);
System.out.println(age + 1);// 30
String scoreStr = "99.5";
// double score = Double.parseDouble(scoreStr);
double score = Double.valueOf(scoreStr);
System.out.println(score + 0.5);// 100.0
4.StringBuilder
- StringBuilder代表可变字符串对象,相当于是一个容器,它里面装的字符串时可以改变的,就是用来操作字符串的
StringBuilder s1 = new StringBuilder(); —>创建一个空白的可变的字符串对象,不包含任何内容
StringBuilder s2 = new StringBuilder(“itheima”); —>创建一个指定字符串内容的可变字符串对象
- 拼接内容
s2.append(12);
s2.append("黑马");
s2.append(true);
System.out.println(s2);// itheima12黑马true
// 支持链式编程
s2.append(666).append("好好学习Java").append(99.2);
System.out.println(s2); // itheima12黑马true666好好学习Java99.2
2.反转操作
s2.reverse();
System.out.println(s2);// 2.99avaJ习学好好666eurt马黑21amiehti
3.返回字符串的长度
System.out.println(s2.length());// 30
4.把String Builder对象又转成String类型
String rs = s2.toString();
System.out.println(rs);// 2.99avaJ习学好好666eurt马黑21amiehti
- 对于字符串相关的操作,如频繁的拼接,修改等,建议用String Builder,效率更高
注意:如果操作字符串较少,或者不需要操作,以及定义字符串变量,建议用String
// 需求:要拼接100万次abc
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 1000000 ; i++) {
sb.append("abc");
}
System.out.println(sb);
5.StringJoiner
StringJoiner s = new stringJoiner(",'); —>间隔符
StringJoiner s = new StringJoiner(",","[", "]");
s.add("java1");
s.add("java2");
s.add("java3");
System.out.println(s);// [java1,java2,java3]
三.常见API(二)
1.Math类
1.取绝对值
public static int abs(int a):取绝对值(拿到的结果一定是正数)
System.out.println(Math.abs(-12)); // 12
System.out.println(Math.abs(12));// 12
System.out.println(Math.abs(-3.14)); // 3.14
2.向上取整
public static double ceil(double a):向上取整
System.out.println(Math.ceil(4.00000000001)); // 5.0
System.out.println(Math.ceil(4.0)); // 4.0
3.向下取整
public static double floor(double a):向下取整
System.out.println(Math.floor(4.0)); // 4.0
System.out.println(Math.floor(4.999)); // 4.0
4.四舍五入
public static long round(double a):四舍五入
System.out.println(Math.round(3.4999));// 3
System.out.println(Math.round(3.5001));// 4
5.求最大值和最小值
public static int max(int a, int b):取最大值
public static int min(int a, int b):取最小值
System.out.println(Math.max(10,20)); // 20
System.out.println(Math.min(10,20)); // 10
6.取次方
public static double pow(double a, double b):取次方
System.out.println(Math.pow(2,2)); // 4
7.取随机数【0.0-1.0)(包前不包后)
public static double random(): 取随机数[0.0 , 1.0) (包前不包后)
System.out.println(Math.random());
2.System
- 终止当前运行Java虚拟机的就不写了😎
public static long CurrentTimeMillis(): —>获取当前系统的时间
返回的时间是long类型的时间毫秒值,指的是从1970-1-1 0:0:0开始走到此刻的总的毫秒值
计算for循环所用时间(s)
long time = System.currentTimeMillis();
System.out.println(time);
for (int i = 0; i < 1000000; i++) {
}
long time2 = System.currentTimeMillis();
System.out.println((time2 - time) / 1000.0 + "s");
3.Runtime
public static Runtime getRuntime() —>返回与当前Java应用程序关联的运行时对象
public void exit(int status) —>终止当前运行的虚拟机,该参数用作状态代码;按照惯例:非零状态代码表示异常终止
public int availableProcessors():—>获取虚拟机能够使用的处理器数
public long totalMemory()—> 返回Java虚拟机中的内存总量
public long freeMemory()—> 返回Java虚拟机中的可用内存量
// 1.public static Runtime getRuntime() 返回与当前Java应用程序关联的运行时对象
Runtime r = Runtime.getRuntime();
// 2.public void exit(int status) 终止当前运行的虚拟机,该参数用作状态代码;按照惯例:非零状态代码表示异常终止
// r.exit(0);
// 3.public int availableProcessors():获取虚拟机能够使用的处理器数
System.out.println(r.availableProcessors());
// 4.public long totalMemory() 返回Java虚拟机中的内存总量
System.out.println(r.totalMemory()/1024.0/1024.0 + "MB");
// 5.public long freeMemory() 返回Java虚拟机中的可用内存量
System.out.println(r.freeMemory()/1024.0/1024.0 + "MB");
4.BigDecimal
- 用于小数的精确计算
- 用来表示很大的小数
构造方法:
构造方法 获取public BigDecimal(double val)对象
public public BigDecimal(double val)
public BigDecimal(String val)
静态方法获取 BigDecimal对象
public static BigDecimal valueOf (double val)
把他们变成字符串封装成BigDecimal对象运算
BigDecimal a1 = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
BigDecimal c1 = a1.add(b1);
BigDecimal c2 = a1.subtract(b1);
BigDecimal c3 = a1.multiply(b1);
BigDecimal c4 = a1.divide(b1);
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
精确小数点几位?
BigDecimal i = BigDecimal.valueOf(0.1);
BigDecimal j = BigDecimal.valueOf(0.3);
BigDecimal k = i.divide(j, 2, RoundingMode.HALF_UP);// 精 确到小数点两位
System.out.println(k);
把BigDecimal转换成double类型的数据
double rs = k.doubleValue();
System.out.println(rs);
构造器和成员方法:
5.Data
创建一个Data对象,代表系统当前时间信息的
Date d = new Date();
System.out.println(d);
拿到时间毫秒值
long time = d.getTime();
System.out.println(time);
把时间毫秒值转换成日期对象,求出2s之后的时间
time += 2 * 1000;
Date d2 = new Date(time);
System.out.println(d2);
直接把日期对象的时间通过setTime方法进行修改(与上面那个效果一样)
即
time += 2 * 1000;
Date d3 = new Date();
d3.setTime(time);
System.out.println(d3);
6.SimpleDateFormat
- 代表简单日期格式化,可以用来把日期对象,时间毫秒值格式化成我们想要的形式
创建简单日期格式化对象,指定的时间格式必须要与被解析的时间格式一样,否则程序会报错
String datestr = "2022-11-11 12:12:11";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
格式化日期对象,和时间 毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String rs1 = sdf.format(d);
String rs2 = sdf.format(time);
System.out.println(rs1);
System.out.println(rs2);
7.Calender
- calender是可变对象,一旦修改后其对象本身的时间将会产生变化
- 获取当前日历对象
Calendar now = Calendar.getInstance();
System.out.println(now);
- 获取日历中的某个信息
int year = now.get(Calendar.MONTH);
System.out.println(year);
int days = now.get(Calendar.DAY_OF_YEAR);
System.out.println(days);
- 拿到日历中记录的日期对象
Date d = now.getTime();
System.out.println(d);
- 拿到时间毫秒值
long time = now.getTimeInMillis();
System.out.println(time);
- 修改日历的某个信息
now.set(Calendar.MONTH,9);// 修改日期为10月份(因为是从0开始)
now.set(Calendar.DAY_OF_YEAR,150);
System.out.println(now);
- 为某个信息增加或者减少多少
now.add(Calendar.DAY_OF_YEAR,100);
now.add(Calendar.DAY_OF_YEAR,-18);
now.add(Calendar.DAY_OF_MONTH,6);
System.out.println(now);
8.LocalDate
- 获取本地日期对象(不可变对象)
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 = ld.getDayOfWeek().getValue();// 星期几
- 直接修改某个信息
LocalDate ld2 = ld.withYear(2099);
LocalDate ld3 = ld.withMonth(12);
LocalDate ld4 = ld.withDayOfMonth(28);
LocalDate ld5 = ld.withDayOfYear(360);
- 把某个信息加多少(plusYears,plusMonths,plusDays,plusWeeks)
LocalDate ld6 = ld.plusYears(2);
LocalDate ld7 = ld.plusMonths(2);
- 把某个信息减多少(minusYears,minusMonths,minusDays,minusWeeks)
LocalDate ld8 = ld.minusYears(2);
LocalDate ld9 = ld.minusMonths(2);
- 获取指定日期的LocalDate对象:public static LocalDate of(int year, int month, int dayOfMonth
LocalDate ld10 = LocalDate.of(2099,12,12);
LocalDate ld11 = LocalDate.of(2099,12,12);
- 判断2个日期对象,是否相等,在前还是在后:equals,isBefore ,isAfter
System.out.println(ld10.equals(ld11));// true
System.out.println(ld10.isAfter(ld));// true
System.out.println(ld10.isBefore(ld11));// false
9.LocalDateTime
(与 LocalDate用法相同,只是这个有(时 分 秒 纳秒)
10.Zoneld
public static Zoneld systemDefault():—>获取系统默认的时区
ZoneId zoneid = ZoneId.systemDefault();
System.out.println(zoneid.getId());
System.out.println(zoneid);
public static Set getAvailableZoneIds():—> 获取Java支持的全部时区Id
System.out.println(ZoneId.getAvailableZoneIds());
把某个时区id封装成ZoneId对象
ZoneId zoneId1 = ZoneId.of("America/New_York");
世界标准时间
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
System.out.println(now1);
获取系统默认时区的ZonedDateTime对象
ZonedDateTime now2 = ZonedDateTime.now();
System.out.println(now2);
11.Arrays
public static String toString(类型[] arr):返回数组的内容
int[] arr = {10,20,30,40,50,60};
System.out.println(Arrays.toString(arr));
.public static 类型[] copyOfRange(类型[] arr, 起始索引,结束索引):拷贝数组9指定范围,包前不包后)
int[] arr2 = Arrays.copyOfRange(arr, 1, 4);
System.out.println(Arrays.toString(arr2));
public static copyOf(类型[] arr, int newLength):拷贝数组,可以指定新数组的长度
int[] arr3 = Arrays.copyOf(arr, 10);
System.out.println(Arrays.toString(arr3));
public static setAll(double[] array, IntTdDoubleFunction generator):把数组中的原数据改为新数据又存进去
double[] prices = {99.8, 128,100};
// 0 1 2
// 把所有价格都打八折,然后又存进去
Arrays.setAll(prices, new IntToDoubleFunction() {
@Override
public double applyAsDouble(int value) {
// value = 0 1 2
return prices[value] * 0.8;
}
});
System.out.println(Arrays.toString(prices));
public static void sort(类型[] arr):对数组进行排序(默认是升序排序)
Arrays.sort(prices);
System.out.println(Arrays.toString(prices));
如何对数组中的对象进行升序 ?
// 制定比较规则了: 左边对象o1 右边对象o2
// 约定1:认为左边对象 大于 右边对象 请返回正整数
// 约定1:认为左边对象 小于 右边对象 请返回负整数
// 约定1:认为左边对象 大于 右边对象 请返回零
Student[] Students = new Student[4];
Students[0] = new Student("蜘蛛精",169.5,23);
Students[1] = new Student("紫霞",163.8,26);
Students[2] = new Student("紫霞",163.8,26);
Students[3] = new Student("至尊宝",167.5,24);
Arrays.sort(Students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(),o2.getHeight());// 升序
}
});
System.out.println(Arrays.toString(Students));