JAVASE高级(一)

1. 面向对象编程

1.1 面向对象基础

在班里有多个学生,每个学生可以看作一个对象,属性包括姓名、成绩等。

  • 开发对象,调用对象对数据处理。
  • 面向对象的好处:符合人类思维习惯,变成更简单、更直观。
  • 对象的本质:一种特殊的数据结构。
  • 对象怎么设计:class也是类,也被称为对象的设计图(模板)。
public class 类名{
1.变量,对象的数据。;
2.方法,描述对象的功能。;
}
//创建对象:
类名 对象名 = new 类名();//Student s1 = new Student();
  • 多个变量指向一个对象,地址赋值(类似于浅拷贝)
Student s1 = new Student();
s1.name = "alex";
Student s2 = s1;
s2.name = "bob";
System.out.println(s1.name);//"bob"

1.2 面向对象内容

  • this变量:this是一个变量,可以用在方法里,来拿到当前对象。

  • 构造器:创建对象时,对象会调用构造器。如果不写构造器,java会创建一个无参构造器。一旦定义了有参构造器,系统不会自动生成无参构造器。

  • 面向对象的三大特征:封装、继承和多态

  • 封装:就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理这些数据的方法设计到一个对象中去。公共:public,私有:private。

  • JavaBean实体类:特殊形式的类。

    • 满足:类中成员变量要私有,要有对外提供的set、get方法。类中必须要有一个公共无参的构造器。
    • 实体类的应用场景:实体类只负责数据存取,而数据的处理交给其他类来完成,以实现数据和数据处理业务分离。

image-20241111172717546

2. Java API

包上用来分门别类地管理不同程序,有利于程序的管理和维护

2.1 String

image-20241111185416810

String s1 ="absaaa";
String s2 = "Absaaa";
char[] chars = s.toCharArray();
s1.equals(s2);//false
s1.equalsIgnoreCase(s2);//true
System.out.println(s1.substring(3));//包前不包后,(aaa)
String info = "这个电影简直是个垃圾,垃圾电影!";
String res = info.replace("垃圾","**");
System.out.println(info.contains("垃圾"));//true
System.out.println(info.startsWith("这个"));//true
String name = "zz,zhw";
String[] names = name.split(',');//[zz,zhw]

String注意事项:

  • String的对象是不可变的,改变会指向新的地址。

  • 只要是以双引号给出的字符串对象,存储在常量池中,而且内容只会存储一份。

  • new String创建字符串对象,每次new出来都是一个新对象,放在堆内存。

    String s1 = "aaaa";
    String s2 = "aaaa";
    Syste.out.println(s1 == s2);//true

2.2 ArrayList

  • 集合:集合是一种容器,用来装数据,类似于数组。
  • 相对于数组,集合大小可变,开发中用的更多。

image-20241111195655502

ArrayList list = new ArrayList();
ArrayList<String> list = new ArrayList<>();//推荐
list.add("你好");
list.add("666");
System.out.println(list);//["你好",666];
list.add(1,"MYSQL");
System.out.println(list);//["你好",MYSQL];
String rs = list.get(1);
System.out.println(list.size());//2
String remove = list.remove(1);//remove = MYSQL
System.out.println(list);//["你好"];
System.out.println(list.remove("你好"));//[];默认删除第一次遇见的数据
list.add("你好");
list.add("666");
System.out.println(list.set(1,"你好"));//["你好","你好"];

3. 面向对象高级

3.1 static

  • 定义:static叫静态,可以修饰成员变量、成员方法。

    • 类变量对应实例变量,类变量只有一份,会被类的全部对象共享,实例变量也被称为对象的变量。
    • 访问:类名.类变量、对象.实例变量。
  • 类方法和实例方法:有无

    • 访问:类名.类方法
    • 注意事项:
      • 类方法可以直接访问类的成员。不可以直接访问实例成员。
      • 实例方法可以直接访问类成员,也可以直接访问实例成员。
      • 实例方法可以出现this关键字,类方法不可以出现this关键字。
  • 代码块,实现类的初始化,为类变量赋值

  • 实例代码块:每次创建对象时,在构造器前执行。

  • 单例设计模式: 确保一个类只有一个对象

    • 私有类的构造器
    • 定义一个类变量记住类的一个对象

3.2 继承

  • 定义:java提供的关键字extends,可以与另一个类建立父子关系。

    • 特点:继承父类的非私有成员。
    • 创建:子类的对象由子类、父类共同完成。
  • 权限修饰符:protected、缺省

    • protected可以在子类中访问,子类对象不可以访问
    • 缺省可以在同目录中访问。
  • 方法重写:子类可以重写一个方法名称、参数列表一样的方法,覆盖父类的方法,即为方法重写。

    • 函数上方加上@Override表示重写(更加安全)。
    • 访问权限必须大于等于父类的权限。
    • 返回值类型需要类型一致或者更小。
    • 私有、静态方法不能被重写。
//就近原则
System.out.println(name);//函数内name
System.out.println(this.name);//子类内name
System.out.println(super.name);//父类内name
  • 子类构造器的特点:
    • 先构造父亲,再构造自己。利用可省略的super调用父类有参构造器。

3.3 多态

  • 定义:多态是在继承\实现情况吓得一种现象,表现为:对象多态、行为多态。

  • 前提:有继承、实现关系;存在父类引用子类对象;存在方法重写

  • 对于方法:编译看左边,运行看右边,对于变量:编译看左边,运行看左边。

People p = new Teacher();
People p2 = new Student();
//行为多态
p.run();//"Teacher"
p2.run();//"Student"
System.out.println(p.name);//父类people
System.out.println(p2.name);//父类people
  • 使用多态的好处:
    • 多态形式下,右边对象是**“解耦合的”**,便于扩展和维护。
    • 可以使用父类类型的变量作为形参,可以接收一切子类对象。
public void (People p){};
  • 存在的问题:多态情况下不能调用子类的独有方法。→类型转换
  • 强转前,可以使用instanceof判断
People p = new Teacher();
Teacher t = (Teacher)p;
Student s = (Student)p;//强制类型转换异常
p instanceof Student;//false

3.4 final关键字、常量

  • final关键字是最终的意思,可以修饰(类、方法、变量)。

    • 修饰的该类被称为最终类,特点是不能被继承了
    • 修饰的方法被称为最终方法,特点是不能被重写了
    • 修饰变量:只能被修饰一次。(局部变量、成员变量)
  • 常量:使用static final修饰的成员变量被称为常量,通常用于记录系统的配置信息。

3.5 抽象类

  • Java中有个关键字为abstract,可以修饰类、方法等。

  • 抽象类的注意事项、特点:

    • 抽象类中不一定有抽象方法,有抽象方法一定是抽象类。
    • 抽象类最主要的特点:不能创建对象,仅作为一种特殊的父类让子类继承实现。
    • 一个类继承了抽象类,必须重写抽象类的全部抽象方法,否则自己也是抽象类。
  • 设计抽象类是为了更好地支持多态。

  • 常见应用场景:模板方法设计模式。建议使用final修饰模板方法(防止使用子类重写)。

3.6 接口

  • Java提供关键字Interface,用这个关键字可以定义一个特殊的结构:接口。
  • 接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类被称为实现类。
  • 一个类可以实现对个借口哦,实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义为抽象类。
public class D implements B, C{
@Override
}
  • 好处:
    • 可以解决单类继承的问题。
    • 面向接口编程,实现业务的灵活切换与拓展。

3.7 内部类

  • 成员内部类、静态内部类

  • 匿名内部类:程序员不需要为这个类声明名字。

    • 匿名内部类本质上是一个子类,并会立即创建出一个子类对象。

    • 作用:用于更加方便的创建一个子类对象。

    • 通常作为一个参数传输给方法。

image-20241116101608170

3.8 枚举

  • 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每个常量记住的都是枚举类的一个对象。
  • 枚举类的构造器都是私有的,对外不能创建对象。
  • 不可以被继承。

3.9 泛型

  • 定义类、接口方法时,同时声明了一个或多个类型变量如、称为泛型类、反省接口
  • ?通配符,在使用泛型时可以代表一切类型。
//上限继承,类型可以为Car或者Car的子类
//extends car为上限,super car为下限
public static void go(ArrayList<? extends Cat> cars){}
public static <T extends Car> void go(ArrayList<T> cars){}
  • 注意事项:
    • 泛型擦除:泛型是在编译阶段,一旦被编译为class文件,就不存在泛型
    • 泛型不支持基本数据类型,只能支持对象类型。

3.10 常用api

  • Object类
//以下方法可进行重写,实现进一步功能(如内容)
public String toString();//返回对象的字符串的表示形式(默认地址)
public boolean equals(Object o);//判断两个对象是否相等(地址)
public Object clone();//对象克隆,protected修饰
//该方法是浅克隆(浅拷贝)
public class User implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedExcepted{
return super.clone();
}
}
User u2 = (User) u1.clone();
  • Objects类
public static boolean equals(Object s, Object b);//先做非空对象,然后比较两个对象
//利用Objects.equal避免空指针,更安全,更好
public static boolean isNull(Object obj);//判断对象是否为null,为null则为true
public static boolean nonNull(Object obj);//上述取反
  • 包装类
    • 把基本类型包装为类
public static Integer valueOf(int i);
int → Integer;
char → Character;
String s = Integer.toString(a);//把基本类型的数据转为字符串
int age = Integer.parseInt(ageStr);//把字符串类型转为对应的基本类型
int age = Integer.valueOf(agestr);
Double score = Double.parseDouble(ageStr);//把字符串类型转为对应的基本类型
  • StringBuilder
    • StringBuilder代表可变字符串对象,相当于一个容器,里面的字符串是可变的,可以用来操作字符串。
    • StringBuilder比String更适合做字符串的修改操作,效率更高,代码更简洁。
//构造器
public StringBuilder();
public StringBuilder(String str);
//方法
public StringBuilder append(任意类型);//添加数据并返回StringBuilder本身
public StringBuilder reverse();//将对象的内容反转
public StringBuilder toString();//转为String
  • StringBuffer

    • 与StringBuilder一模一样
    • StringBuilder是线程不安全的,StringBuffer是线程安全的。
  • StringJoiner

    • 用来操作字符串,可以看成一个容器,创建后的内容可变。
    • 好处:不仅可以提高字符串的操作效率,在有些场景下用它操作字符串,代码更加简洁。
  • Math

    • 提供对数据操作的静态方法。
public static double abs();//绝对值
public static double ceil();//向上取整
public static double floor();//向下取整
public static long round();//四舍五入
public static double pow(double a ,double b);//取次方
public static double random();//取随机数【0.0,1.0)
  • System
public static void exit(int status);//终止虚拟机,一般不要用
public static long currentTimeMillis();//获取当前电脑时间,判断程序的运行时间
  • Runtime
    • 代表程序所在的运行时间,是一个单例类。
Runtime r = Runtime.getRuntime();
r.availableProcessors();//返回Java虚拟机中的处理器数
public long r.totalMemory(){}//可用内存容量:freeMemory()
r.totalMemory()/1024.0/1024.0;//返回虚拟机的内存(MB)
Process p = r.exec("path");//启动某个路径的文件
Tread.sleep(5000);
p.destroy();//销毁,关闭程序
  • BigDecimal
    • 用于解决浮点型运算时,出现结果失真的问题。
public BigDecimal(String val);//构造器
double a = 0.1;
BigDecimal a1 = BigDecimal.valueOf(a);//a为double类型
double b = 0.2;
BigDecimal b1 = BigDecimal.valueOf(b);
BigDecimal c1 = a1.add(b1);//substract,multiply,divide
BigDecimal k = i.divide(j,2,RoundingMode:HALF_UP);//除法(0.1/0.3)
double result = k.doubelValue();//转为double
  • 日期和时间(传统)
    • Date
    • SimpleDateFormat
    • Calendar
//Date
Date d =new Date();
System.out.println(d);//系统当前时间
long time = d.getTime();//拿到时间毫秒值
time +=2*1000;
Date d2 = new Date(time);//2秒之后的时间
d2.setTime(time);//设置时间
//SimpleDateFormat,格式化日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
String re = sdf.format(d);
System.out.println(rs);//2024年11月16日 17:02:24 周六 下午
String dateStr = "2024-11-16 12:12:11";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d2 = sdf2.parse(dateStr);//解析String类
//Calendar
Calendar date = Calendar.getIntance();
int year = date.get(Calendar.YEAR);
Date d = date.getTime();
date.set(Calendar.MONTH,9);//设置时间
date.add(Calendar.DAY_OF_YEAR,100);
  • 日期和时间(jdk8之后)
    • LocalDate、LocalTime、LocalDateTime
    • ZoneId、ZoneDateTime
    • Period、Duration
//LocalDate、LocalTime、LocalDateTime
LocalDate ld = LocalDate.now();//年月日(日期)
int year = ld.getYear();
LocalDate ld2 = ld.withYear(2099);//localDate为不可变对象
LocalDate ld3 = LocalDate.of(2099,12,12);
LocalDateTime ld4 = LocalDateTime.now();
LocalDate ld = ld4.toLocalDate();
LocalTime lt = ld4.toLocalTime();
LocalDateTime ld5 = LocalDateTime.of(ld,lt);
equals\isBefore\isAfter;
//ZoneId\ZoneDateTime
ZoneId zoneId = ZoneId.systemDefault();
ZoneId zoneId1 = ZoneId.of("America/New_York");
ZonedDateTime now = ZonedDateTime.now(zoneId1);
//Instant(秒、纳秒)

image-20241118144141174

  • Arrays
int []arr = {10,20,30,40,50};
System.out.println(Arrays.toString(arr));//[10,20,30,40,50]
int []arr2 = Arrays.copyOfRange(arr,1,4);//[20,30,40]
int []arr3 = Arrays.copyOf(arr,10);
//Arrays实现类对象的比较:重写Comparable接口,重写compareTo方法
public class Student implements Comparable{
.....
@Override
public int compareTo(Student o){
return o.age - this.age;
}
}
//第二种方法Comparator比较器
Arrays.sort(students, new Comparator<Student>(){
@Override
public int compare(Student o1,Stdent o2){
return Double.compare(o1.getHeight(),o2.getHeight());
}
})
  • Lambda表达式
    • Lambda表达式是JDK8开始新增的一种语法形式,用于简化匿名内部类的代码。
    • lambda表达式并不是能简化全部匿名内部类的写法,只能简化函数式接口的匿名内部类
    • 函数式接口:有且仅有一个抽象方法的接口。标记:@FunctionalInterface
interface Swimming{
void swim();
}
Swimming s = new Swimming(){
@Override
public void swim(){
System.out.println("学生快乐游泳");
}
};
Swimming s =()->{
System.out.println("学生快乐游泳");
};
//简化
Arrays.sort(students, ( o1, o2) ->Double.compare(o1.getHeight(),o2.getHeight()));
  • 方法引用
    • 静态方法引用:标志(::)
    • 特定类型的引用:如果在Lambda表达式中只是调用一个实例方法,并且参数列表中的第一个参数是作为方法的主调,后面的所有参数是作为该实例方法的入参时,可以使用特定类型的方法引用。
    • 构造器引用:不常见
public class CompareByData{
public static int compareByAge(Student o1,Student o2){
return o1.getAge()-o2.getAge();
}
public int compareByAgeDesc(Student o1,Student o2){
return o2.getAge()-o1.getAge();
}
}
//静态方法引用
Arrays.sort(students,(o1,o2)->o1.getAge()-o2.getAge());
Arrays.sort(students,(o1,o2)->CompareByData.compareByAge(o1,o2));
Arrays.sort(students,CompareByData::compareByAge);
//实例方法引用
CompareByData compare = new CompareByData();
Arrays.sort(students,compare::compareByAgeDesc);//降序
//特定类型的引用
Arrays.sort(names,new Comparator<String>(){
@Override
public int compare(String o1,String o2){
return o1.compareToIgnoreCase(o2);
}
});
Arrays.sort(names,(o1, o2)->o1.compareToIgnoreCase(o2));
Arrays.sort(names,String::compareToIgnoreCase);