JAVA菜鸡笔记

花有重开日,人无再少年

五斗米不能没有,但追求决不局限于此——月亮与六便士

JAVA

  • 一定贯彻一个思想——面向百度编程!!!

目录

零、入门常识

1、👶IEDA

JetBrains IntelliJ IDEA 下载地址JetBrains IntelliJ IDEA 官网

IDEA优化:Setting优化

1.1、插件

已安装

未安装

1.2、反编译(hashcode)

  • 软件 XJad

  • 编写java——IDEA翻译成class(字节码文件)——反编译(IDEA自带)

  1. Project Structure复制路径——粘贴到文件夹——找到CLASS文件
  2. 在IDEA中"struct"右键——open in explorer——找到intellij IDEA文件——将CLASS文件复制到intellij IDEA文件目录下
  3. 返回IDEA——有个01标志

1.3、工具栏

View篇
  1. Tool Windows——界面上大的方块栏
  2. Appearance——边条框
  • 查询

2、与机器对话

2.1、DOS命令

1 DOS是什么
  • 解释:Disk Operating System的缩写,意思是“磁盘操作系统”
  • 系统:DOS就是人给机器下达命令的集合,是存储在操作系统中的命令集
  • 基本用途:有了DOS,我们就可以更容易理解怎么给机器下命令,不必去深入了解机器的硬件结构,也不必去死记硬背那些枯燥2进制数字的机器命令,只需通过一些接近于英语的DOS命令,我们就可以轻松地完成绝大多数的日常操作
  • 区别:图形化操作界面(Windows,linux)//DOS命令操作界面
2 打开DOS控制台(cmd)方式
  1. 开始---命令提示符

  2. win +R --- 输入cmd

3 常用命令
#盘符切换	D:
#查看当前目录下的所以文件	dir
#进入文件	cd
		   cd Music	进入文件
		   cd /d C:\Users\86156\Desktop	路径切换
		   cd..	返回上一级目录
#创建文件	cd> Music	//创建目录	md Music
#删除文件	del Muisc	//删除目录 	rd Music
#清除		cls
#推出终端	exit
#查看电脑IP 	ipconfig
#打开应用程序	calc	计算器
		   mapaint	画笔工具
#网站ip地址	ping命令---ping www.bilibili.com---复制,右键粘贴

3、编程开发工具

4、🌻java开发环境安装

详细安装:狂神说

(视频附带删除版本)

4.1、问题

解决javac不是内部命令或外部命令(cmd中运行Java)

在视频安装基础上要加个CLASSPATH .;%JAVA_HOME%\lib

详情:百度

image-20210813115622252

4.2、JDK 和 SDK 的区别

1、SDK 是Software Development Kit的缩写,中文意思是“软件开发工具包”。这是一个覆盖面相当广泛的名词,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”。SDK是一系列文件的组合,它为软件的开发提供一个平台(它为软件开发使用各种API提供便利)。

2、JDK (Java Development Kit)是Sun Microsystems针对Java开发员的产品。自从Java推出以来,JDK 已经成为使用最广泛的Java SDK(Software development kit)。

3、可以认为jdk只是sdk的一种(子集),因为它是开发 java 程序的一个平台,开发其他程序的sdk可以没有jdk。比如你下载了一个软件开发平台 eclipse-SDK-3.2.2-win32.zip,它本身里面是没有jdk的。但是只要开发java程序就必须使用jdk。

一、基础学习

基本名词解释

1.1、注释comment

  • 单行注释
  • 多行注释
  • 文档注释
  • 注释颜色修改setting--Editor--java--comments

1.2、关键字

1.2、标识符

包含四部分:类名,变量名,方法名.....(自己随便定);关键字(系统定义)

关键字大全

1、import

  • 导入这个类所存在的包

2、this

  • 指向当前实例对象的引用(取地址)
    • 实例化(instantiate)是指在[面向对象]的编程中,把用类创建对象的过程称为实例化。是将一个抽象的概念类,具体到该类实物的过程。实例化过程中一般由类名 对象名 = new 类名(参数1,参数2...参数n)构成。
  • 结合继承 susper 理解

3、final

final 修饰的实例字段一经设置就不能修改

  • 在对象构造之后,这个值不会再改变,即没有set()方法
public class Body {
    
    final double PI =3;
	private  int age;
	private final String name = "lvtu";
}

1.3、数据类型

  • 八大数据类型——根据存储的字节数不同分类

  • 引用类型

    • image-20220330101901811
  • 强制数据转换(多位转低位)

    • 格式:(想要转换的数据类型)+ 带转换的变量名

    • double x = 9.998;
      int y = (int)x;//x 输出9——因为浮点数转整数是通过截断小数部分	
      
  • 数据拓展

1.4、常量、变量

1、常量

final 类型 常量名;//常量名一般大写

2、变量

记忆:存储空间一定——一个小格子

修饰符 类型 变量名;//修饰符可省略

3、作用域

💖实例变量

就是普通的,在类内部,方法外部

💖类变量/静态变量

在实例变量前,只需要加一个static,便可直接输出,不需要New对象(属性、方法)

💖局部变量/内部变量

在方法里面

  • 实例变量和类变量的区别
    1. 都是在类内部,方法外部
    2. 类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象
    3. 类变量不需要New对象

代码实现

package com.journey.base;

import java.util.Scanner;

public class 变量05 {

    //作用域:类变量+实例变量+局部变量

    //类内部,方法外部
    //1、类变量(只需要加一个static,便可直接输出,不需要New对象,属性和方法都适用)
        static double salary =2500;

    //2、实例变量(从属于对象,而对象又在这个“变量05”类中)——若不初始化,默认为0 0.0  false null
        String name;
        int age;

    //main方法
        public static void main(String[]args){

        //3、局部变量(必须声明变量和初始化值)
            int i = 10;
            System.out.println(i);

        /*输出实例变量(New一个对象)
            变量类型 变量名 = new com.journey.base.变量类型();*/
            变量05 dome4 = new 变量05();//声明

            dome4.name = "旅途";//创建对象的属性并赋值
            dome4.age  =3;

            System.out.println("请输入成绩:");
            变量05.text();      //创建对象的方法

            System.out.println(dome4.name);
            System.out.println(dome4.age);

        //输出类变量——static
            System.out.println(salary);

    }
}



1.5、运算符operator

  • 运算符的优先级

    • 优先级 运算符 结合性
      1 ()、[]、% . 从左到右
      2 !、+(正)、-(负)、~、++、– 从右到左
      3 *、% 从左到右
      4 +(加)、-(减) 从左到右
      5 << 、>> 、>>>(移位操作) 从左到右
      6 <、<=、>、>= 从左到右
      7 == 、 != 从左到右
      8 & 从左到右
      9 ^ 从左到右
      10 | 从左到右
      11 && 从左到右
      12 || 从左到右
      13 ?: 从右到左
      14 &=、 从右到左
  • 基本运算

    • 一元运算(包含自增自减,数学运算)
    • 二元运算(包含布尔关系、、字符串运算)
    • 三元运算(条件语句)
  • 逻辑运算

    • 与、或、非

1.6、包机制

image-20220322110338919

1.7、JavaDoc

生成 JavaDoc

1.8修饰符

1、static

静态属性+方法

  • static 修饰的属性方法可以直接被调用和共享
    • 而未修饰时,每个对象私用
  • 静态属性

image-20220325110204440

image-20220325110326591

  • 静态方法

    • ✨静态方法是不在对象上执行的方法(无需new 对象),例如不需要构造Math 类的任何对象,就可直接调用 Math.pow(x,a)

      • double e = Math.pow(2,3);
        
    • 可以通过类名来调用这个方法

      • Util.geTime()——下面漫画
        
    • 静态方法没有 this 参数的方法(this 方法指示这个方法的隐式参数),而它需要的参数都通过显示参数提供

      • image-20220331102014909
    • 类名调用

image-20220325110438523

2、public

公用模式,可跨包使用,凡是环境下的类和方法都可以使用,需导入包

  • 你分两个文档写即可;

    同文档,里面是仅允许一个public(不管是接口,还是类) 权限存在,这是规矩,Java定的!

    • 只有一种情况可以,那就是内部类,允许存在public权限修饰的类,和接口

      当然这个是能算的上,外部类的成员了,所以他可以用public 修饰!

3、private

  • 私有属性
    • 可通过(set)方法进行操作
    • 当属性被 final 修饰时,将不可以被操作
  • 私有方法
    • 也可通过(set)方法进行操作

image-20220323110654156

private Spring name;
public void setName(String name) {
   this.name = name;
}

public String getName() {   
    return name;
}

        student lvtu = new student();

        lvtu.setName("旅途");
        System.out.println(lvtu.getName());
  • 方法

4、protected

  • protected 修饰的属性或方法,在类中像public,在对象中像private

image-20220324102530190

public class Body {
    protected int age;
    public void add(int age)
    {
        this.age = age;
    }
}
class test {
    protected int ff;
    public/protected void adds(int age)
    {
        this.ff = age;
    }
    public static void main(String[] args) {
        
        Body body = new Body();
        body.add(5);
        body.ff;//报错
        body.adds();//报错!
    }
}

二、流程控制

指在程序运行时,个别的指令(或是陈述、子程序)运行或求值顺序

2.1、用户交互Scanner

  • 作用:获取用户数据
  • 基本语法 Scanner s = new Scanner(system.in)——固定
    • 通过 next() 和 next Line() 方法获取
    • 需要导入Scanner包
package com.journey.scanner;

import java.util.Scanner;

public class 运算交互 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double sum = 0;
        int m = 0;	

        while (scanner.hasNextDouble()) {  //注意是while循环!!——如果输入的条件不符,则跳出循环
            double x = scanner.nextDouble(); //nextDouble()——获取输入的字符串

            m = m + 1;  //
            sum = sum + x;
            System.out.println(m+"个数的平均数:"+(sum/m));
        }
        System.out.println(m+"个数的总和:"+sum);
        System.out.println(m+"个数的平均数:"+(sum/m));

        scanner.close();
    }

}

1、IF语句

  • 关系表达式 和 逻辑表达式 之分
  • if 后面不可加分号
  • if 只能执行一条分支
package com.journey.struct;

import java.util.Scanner;

public class if选择结构 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入内容:");
//单独执行一项,把其他的注释掉
         //if单选
            String s = scanner.nextLine();//由此可见不需要嵌套在if,while中
            if(s.equals("journey")){    //equals是匹配,匹配相同返回true
                System.out.println(s);
            }
            System.out.println("End");
        //if双选
            Double score = scanner.nextDouble();
            if(score>=60){
            System.out.println("及格");
        }else {
            System.out.println("不及格");
        }
    //if多选
        Double scores = scanner.nextDouble();
        if(scores==100){
            System.out.println("满分");
        }else if(scores<100&&scores>=90){
            System.out.println("A");
        }else if(scores<90&&scores>=80){
            System.out.println("B");
        }else if(scores<80&&scores>=70){
            System.out.println("C");
        }else if(scores<70&&scores>=60){
            System.out.println("D");
        }else if(scores<60&&scores>=0) {
            System.out.println("E");
        }else {
            System.out.println("成绩不合法");
        }
        scanner.close();

    }
}

2、While 循环

  • while 后面不可加分号
  • 语句都用花括号括起来
  • scanf 可以嵌套在循环中使用
while(判断条件)
{
	...
}
package com.journey.struct;

public class while循环结构 {
    public static void main(String[] args) {
        int i = 0;
        int sum = 0;

        while(i<=100){
            sum = sum+i;
            i++;
        }
        System.out.println(sum);
    }
}

3、For 循环

  1. for(初始化;判断条件;操作)
  2. 💕{....} 等价于 ;
	int i,total ;
	for (i =1,total =1; i <= 100; i++)
	{
		total = total + i;
	}
	printf("1 到 100 的和为:%d", total);

  • 增强 for 循环——foreach

作用:简化数组和集合的遍历

增强for的底层依赖的是迭代器🌻

for(数据类型  变量名 : 数组或者集合对象){//假如不确定数据类型,统一(Object obj: )
	//打印
    System.out.println(变量名);
}

4、continue 结束本次循环语句

	int i, total;
	for (i = 1, total = 1; i <= 100; i++)
	{
		if (i % 2 == 0) {
			continue;
		}
		total = total + i;

	}
	printf("1 到 100 的奇数和为:%d", total);

5、break 结束循环语句

	int i, total;
	for (i = 1, total = 1; i <= 100; i++)
	{
		if (i >=2000) {
			break;//for循环结束,吓一挑输出printf
		}
		total = total + i;

	}
	printf("1 到 100 的奇数和为:%d", total);

2.6、💖debug的利用💖

img

在这里插入图片描述

三、对象

  • 本质:以类的形式组织代码,以对象的形式封装数据
    • 类和结构体有点类似
  • 面向过程面向对象 的区别
    • image-20220320221846813
image-20220320221922806

image-20220320222048632

4.1、创建对象

  • 漫画解释

image-20220322095452970

  • 代码实现
    • import关键字—导入包作用
import java.util.Scanner;//

public class test {
    //属性
    String name;
    int age;
    static double salary = 2500;//static静态方法,可在main方法外执行

    //方法1——静态方法(有static)
    public static void text() {
        Scanner scanner = new Scanner(System.in);
        if (scanner.hasNextDouble()) {
            Double score = scanner.nextDouble();

            if (score >= 60) {
                System.out.println("及格");
            } else {
                System.out.println("不及格");
            }
        }
        scanner.close();//勿忘
    }

    //方法2——非静态方法(需要New一个lvtu)
    public int max(int x, int y) {
        if (x > y) {
            System.out.println(x);
        } else {
            System.out.println(y);
        }
        return 0;
    }
}
class 对象 {	//注意这里没有public
    public static void main(String[] args) {

        test lvtu = new test();//声明——对象的核心

        lvtu.name = "旅途";//创建对象的属性并赋值
        lvtu.age = 3;

        System.out.println(lvtu.name);
        System.out.println(lvtu.age);
        System.out.println(lvtu.salary);

        System.out.println("请输入成绩:");
        test.text();      //创建对象的方法


        lvtu.max(5,9);//非静态方法需要创建对象——类 lvtu = new 类();
    }

}

✨原理

详情

💖Bemo demo=new Demo();
这一条语句,其实包括了四个动作:
1)右边的“new Demo”,是以Demo类为模板,在堆空间里创建一个Demo对象。

(Elemtype*)malloc(sizeof(Elemtype))

2)末尾的()意味着,在对象创建后,立即调用Demo类的构造函数,对刚生成的对象进行初始化。

✨java与c 主要区别 将数据(实例字段)通过构造器(方法)封装,创建出来的对象通过调用构造器(方法)给蛇初始化长度、年龄...

3)左边的“Demo demo”创建了一个Bemo类引用变量,它存放在栈空间中。也就是用来指向Demo对象的对象引用

Bmeo * demo ——初始化结构体指针的过程

4)“=”操作符使对象引用指向刚创建的那个Demo对象

demo=(Elemtype *)malloc(sizeof(Elemtype))
  • 对象引用对象的关系

    • java 语言中使用了引用代替了指针,引用实质就是指针,但它是受控的、安全的。我们知道,一个引用,比如说person p 等于new person,实际上就是p这个引用指向了这个对象实体,所以本质上就是指针

    • 一个对象引用可以指向一个对象

      Bemo demo;//一个对象引用
      demo=new Demo();//一个对象引用指向一个对象
      

        也可以被多个对象引用同时引用——创建多个对象

      Bemo demo1,demo2,demo3;//创建多个对象引用
      demo1=new Demo();
      demo2=demo1;
      demo3=demo2;//创建对象,并被多个对象引用指向
      

img

栈、堆、方法区
  • 堆内存

    可被所有线程共享——所谓共享就是,都取向目标的地址

    • 存放 new 的对象和数组
    • 不会存放别的对象引用
  • 栈内存

    • 存放基本变量类型
    • 引用对象的变量
  • 方法区

    可被所有线程共享

    • 包含了所有👀 class 和 static 变量
  • 三者关系

image-20220329115612937

4.2、构造器(构造函数)

1、默认构造器

Snake S1 = new Snack()
//所以类的属性默认为0

image-20220322114800788

2、自定义构造器

  • 与类名相同
  • 构造器没有返回值
public Sanke(int age,int heigh...)
{
    age = 5;
    ...
}

image-20220322115759600

  • 代码实现
public class person {
//一个类什么也没有,也会存在构造器
    String name;

//1、使用new,本质是在调用构造器
//2、用来初始化值(可减少main行数)
    public person() {   //无参——默认隐藏
   }

    //重载!——有参,无参之间关系

    public person(String name) {    //有参
        this.name = name;
    }
/*    Alt+Insert——有参
                  无参-select None
                 自动填充*/
}

class Application {
    public static void main(String[] args) {

        person journey=new person("lvtu");

        System.out.println(journey.name);
    }

}

3、构造函数的重载

image-20220322120325103

4.3、三大特性

1、封装

  • this 关键字:指向当前实例对象的引用

属性私有:用get/set可以调用这些属性和方法

🌻get/set方法快捷键:右键>Gennrate>getter and setter

🌻构造器快捷键:右键>Gennrate>Constructor

构造器set 方法的作用是等价的,也就是说二者只写一个即可

image-20220323113116204

  • 代码实现
//封装作用:加密+初始化 private
public class student {
    private String name;
    
	public void setName(String name) {
       this.name = name;
    }
    
    public String getName() {   
        return name;
    }

}

class Application {
    public static void main(String[] args) {

        student lvtu = new student();

        lvtu.setName("旅途");
        System.out.println(lvtu.getName());

    }
}

2、继承

super关键字

image-20220324101500104

  • 继承的优点

image-20220324101940691

  • super 关键字

image-20220324102712205

  • 代码实现
public class Person {

    public Person() {//无参构造器
        System.out.println("父类无参");
    }

  	public Person(String jojo){//有参
      System.out.println("父类有参");
  

    //public-private私人方法无法被继承
    public void print(){    //方法
        System.out.println("lala");
    }
    protected String name = "lvtu";//属性

}

class Student extends Person {
//当父类有无参,则子类想要调用,
 public Student(){//构造器
  super();//默认存在,且默认调用父类的无参
  //super("有参") ;   //若调用有参,则...,且有无参不能同时存在
                   // Call to 'super()' must be first statement in constructor body
   System.out.println("子类");
 }


 public void print(){   //方法
  System.out.println("拉拉");
 }
 private  String name = "journey";//属性
    
 public void text(String name){
  System.out.println(name);//"旅途"
  System.out.println(this.name);//journey
  System.out.println(super.name);//lvtu
 }

 public void text1(){
  print();//拉拉		在text方法中调用print方法;等价this.print()
  this.print();//拉拉
  super.print();
 }     
}

class Applicate {
    public static void main(String[] args) {
        Student student = new Student();
//new 必须是被调用的类的名字
        student.text("旅途");
        student.text1();
    }
}

3、多态

解决继承中,子类和父类有同名方法问题

  • 多态可以让 不同的子类 保存在父类的对象变量中,然后由父类对象变量调用子类中的同名方法
    • 子类编写方法实现,父类调用
3.1介绍

image-20220324121920468

  • 此场景下,调用父类方法

image-20220324122020003

3.2对象变量与对象
  • 类比指针变量与指针

image-20220324112233249

✨3.3面向对象思想
  • 在多态中展现出来

image-20220324112723366

  • 代码实现

    //父类
    Class MonstBase
    {
        public void attack()
        {System.out.println("啄")}
    }
    //子类
    class Dragon extends MonstBase
    {
        @Override
        public void attack()
        {System.out.println("铁头功")}	
    }
    //子类
    class Pig extends MonstBase
    {...}
    //子类
    class Cayman extends MonstBase
    {...}
    
    //测试类
    class test
    {
        public static void main(String[] args) {
            MonstBase monst0 = new MonstBase();
    		MonstBase monst1 = new Dragon();	
            MonstBase monst2 = new Pig();
            MonstBase monst3 = new Cayman();
            
            monst1.attack();//调用
        }  
    }
    

4.4、抽象类

兼具类和接口的特点

类——不能实现多继承

接口——不能有变量,也不能创建对象,不易出错,且方法不需要具体的代码

//接口1
abstract Class IMonstBase
{
    public abstract void attack();
}

//子类
class Dragon extends IMonstBase
{
    @Override
    public void attack()
    {System.out.println("铁头功")}
    

}
//子类
class Pig extends IMonstBase
{...}
//子类
class Cayman extends IMonstBase
{...}

//测试类
class test
{
    public static void main(String[] args) {
		IMonstBase monst1 = new Dragon();	
        IMonstBase monst2 = new Pig();
        IMonstBase monst3 = new Cayman();
        
        monst1.attack();//调用
    }  
}

4.5、💖接口

多态中,父类对象变量调动虽然方便,但容易出错——接口不能有变量,也不能创建对象,不易出错,且方法不需要具体的代码

  • 实现多继承(接口)

1、原理

将接口看作一种类

  • 接口就是父类
  • 接口实现类就是子类

image-20220412105837190

image-20220325101313904

  • 代码实现
//接口1
interface IMonstBase
{
    public void attack();
}
//接口2
interface IMonstBase2
{
    public void attack1();
}
//子类
class Dragon Implements IMonstBase,IMonstBase2//实现多继承(接口)
{
    @Override
    public void attack()
    {System.out.println("铁头功")}
    
    @Override
    public void attack1()
    {System.out.println("铁头功")}
}
//子类
class Pig Implements IMonstBase
{...}
//子类
class Cayman Implements IMonstBase
{...}

//测试类
class test
{
    public static void main(String[] args) {
		IMonstBase monst1 = new Dragon();	
        IMonstBase monst2 = new Pig();
        IMonstBase monst3 = new Cayman();
        
        monst1.attack();//调用
    }  
}

四、方法

方法是语句的结合,它们在一起执行某些功能

3.1、创建方法

修饰符 返回值类型 方法名(参数类型 参数名)
{
	...
}
public static void add(int a)//public static 均为修饰符
{
	....
}

3.2、调用方法

  • 用分量符号 “ . ”

3.3、重载方法

所有的方法都具备重载的能力,类比于构造器的重载

  • @Override

3.4、可变参数

  • (double...Numbers)——可输入n个数据
public class 可变参数 {
    public static void main(String[] args)
    {
   text(5,6,82,92,102,200.2);
    }
    public static void text(double...Numbers){
        Double result = Numbers[0];//初始化

        for(int i=0;i<Numbers.length;i++){
            if(Numbers[i]>result){
            result =Numbers[i];
            }
        }
        System.out.println(result);
    }
}

3.5、✨递归

五、数组

  • 数据描述的是相同类型的若干个数据,按照一定的先后次序组合而成

5.1、创建数组

  • 静态初始化
  • 动态初始化
package com.journey.array;

public class 初始化 {
    public static void main(String[] args) {
        //1、静态初始化————创建+赋值
        int[] a={1,2,3,45,6};
        System.out.println(a[3]);

            //计算所有元素的和
            int sum = 0;
            for (int i = 0; i <a.length ; i++) {
                sum= sum+a[i];
            }
            System.out.println(sum);
        //2、动态初始化
        int[] b = new int[5];
        b[2] = 5;
        System.out.println(b[2]);
        System.out.println(b[3]);


    }
}

5.2、二维数组

package com.journey.array;

public class 二维数组 {
    public static void main(String[] args) {
        int[][] array = new int[3][2];
        //int[][] array = {{0,0},{0,0},{0,0}};

        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.println(array[i][j]);
            }

        }
    }
}

5.3、Arrays类

1、sort排序方法

package com.journey.array;

import java.util.Arrays;

public class Arrays类 {
    public static void main(String[] args) {
        int[] a = {20,52,86,42};
        int[] b = new int[3];

        System.out.println(a);//[I@1b6d3586

        Arrays.sort(a);//升序
        System.out.println(Arrays.toString(a));

    }
}

六、异常处理

  • try...catch

七、常用类

千锋教育

7.1、内部类

大前提:在一个类的内部再定义一个完整的类

Class Outer{
	Class Inner{
	
	}
}

特点

  • 内部类同样会在 bin 目录下生成类文件——Outer$Inner.class
  • 当外部类、内部类存在重名属性时,会优先访问内部类属性
  • 优势:Inner 类可以通过方法(提供内部功能组件)直接访问 Outer 类中的私有成员,而不破坏封装
    • 其实也是封装的思想,直接省略了 get/set 方法
public class Body {
    private String name;

    class Header{
        //private String name;
        
        public void show(){
            //当外部类、内部类存在重名属性时
            //System.out.println(Body.this.name);
            
            System.out.println(name);
        }
    }
}

1、普通(成员)内部类

  • 级别和属性和方法(实例变量)相同
  • 内部不能定义静态成员 static /但可以是静态常量 static final
public class outer {
    private String name;

    class inner{
        public Spirg address;
        
        public void show(){
            System.out.println(name);	//可写成(outer.this.name)✨
            System.out.println(address);// 可写成(this.address) 
        }
    }
}
class test {
    public static void main(String[] args) {
/*        outer outer = new outer();//创建外部类对象
        outer.innter innter = outer.new innter();//创建内部类对象*/
        //等价于(合二为一)
        outer.innter innter= new outer().new innter();

        innter.show();
    }
}

2、局部内部类

  • 定义在方法里面,对外界完全隐蔽
  • 作用范围创建对象只能在方法里面
  • 局部内部类访问外部类当前方法的局部变量时,因无法保证变量的生命周期与自身相同,变量必须修饰为 final
package com.进阶.常用类.内部类.局部内部类;

import com.进阶.常用类.内部类.静态内部类.outers;

public class outeds {
    private String name = "1";
    private int age = 21;

    public void say() { //
       String add = "方法里";//前面默认有 final 常量

        class innteds {
            String name = "旅途";
            int high = 32;

            public void text() {
                System.out.println(name);//优先输出内部类(当同名时)
                System.out.println(age);
                System.out.println(outeds.this.name);
                System.out.println(add);
                System.out.println(high);
        }
    }
    //创建局部内部类对象
        innteds innteds = new innteds();
        innteds.text();
    }

}
class Application {
    public static void main(String[] args) {
        outeds outeds = new outeds();
        outeds.say();
    }
}

3、匿名内部类

  • 没有名字的局部内部类(特征与局部内部类相同)
  • 必须实现继承或接口
  • 优点:定义类、实现类、创建对象的语法合并,且只能创建一个该类的的对象
interface Usb {

    void service();
}
class Mouse implements Usb{
    @Override
    public void service() {
        System.out.println("接口成功");
    }
}

public class Application {
    public static void main(String[] args) {
        //创建接口类型的变量
/*        Usb usb = new Mouse();
        usb.service();*/

        //局部内部类
/*        class joun implements Usb{

            @Override
            public void service() {
                System.out.println("局部内部类");
            }
        }
        Usb usb = new joun();
        usb.service();*/

        //匿名内部类
        Usb usb = new Usb() {	//若为多态则Usb()改为父类名称
            @Override
            public void service() {
                System.out.println("匿名内部类");
            }
        };
        usb.service();
    }
}

4、静态内部类

  • 级别和外部类相同(就因为加了个static)
  • 只有静态内部类可以被 static 关键字修饰,普通类则不能
  • 作用:有时候不想生成外部类的引用(创建对象的过程),则可以将内部类声明为 static
    • outer.innter innter= new outers.innter()
package com.进阶.常用类.内部类.静态内部类;

import com.进阶.常用类.内部类.成员内部类.outer;

public class outers {
    private String name = "1";
    private int age = 21;

    public void say() {
        System.out.println("方法类输出");
    }

    static class innter {   //多了个static
        String name = "旅途";
        int high = 32;

     outers outers = new outers();//需要new,因为由于static,使得outers和innter并列

        public void text() {
            System.out.println(name);//优先输出内部类(当同名时)
            System.out.println(outers.age);
            System.out.println(outers.name);//输出外部
            System.out.println(high);
            outers.say();

        }
    }
}

class Application {
    public static void main(String[] args) {

       outers.innter innter= new outers.innter();//注意是创建的 Inner 类对象

        innter.text();
    }
}

7.2、Object类

所有类的父类,继承树的最顶层(所有类默认 excends Object),Object 类所定义的方法(查看 API),是所有对象都具有的方法

类型type 方法
类<?>——类的类型 getclass() 返回类对象运行时类的Class对象
int hashcode() 返回对象的哈希码值。
string toString() 返回对象的字符串表示形式
boolen equals() 判断两个对象是否相等
protected void finalize() 回收垃圾对象
  • 该类下的常用构造方法:

1、getClass() 方法

作用:返回类的类型——类等到学到反射再学习👀

public class Body {
    private String name;
    private int age;

    public Body(String name, int age) {	//构造器
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}


class test {
    public static void main(String[] args) {

        Body s1=new Body("lvtu",15);
        Body s2=new Body("lvtu",16);

        Class class1 = s1.getClass();
        Class class2 = s2.getClass();
        if(class1==class2)
        {
            System.out.println("s1和s2属于同一类型");
        }else{
            System.out.println("s1和s2不属于同一类型");
        }

    }
}

2、hashcode() 方法

public int hashcode(),作用:返回该对象的哈希码值(整数型)

哈希值是根据对象的地址、字符串、数字使用 hash 算法算出的 int 类型的数值

相同的对象具有相同的哈希码值

System.out.println("s1.hashcode()");//输出366712642
System.out.println("s2.hashcode()");//输出1829164700
  • 重写 hashcode 方法

3、toString() 方法

public string toString(), 作用:返回对象的字符串表示形式

常通过 toString 方法的重载(覆盖),来得到我们想要的内容和形式

✨当然,IDEA提供了很多 toString 构造方法

  • 一般形式
System.out.println("s1.toString()");//输出com.company.Body@1b6d3586
  • 重载 toString 方法 ——通过查看源码,知道(修饰符 返回值类型 方法名)

    • 快捷键:右键>Gennrate>toString()

    • //源码
      public String toString() {
              return getClass().getName() + "@" + Integer.toHexString(hashCode());
          }
      //方法重载
          @Override
          public String toString() {
              return "Body{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      System.out.println("s1.toString()");//输出Body{name='lvtu', age=15}
      

4、equals() 方法

比较两个对象是否相等(实质上是比较两个对象的地址)

✨通过方法覆盖,比较两个对象内容是否相同——五步骤

  • System.out.println(s1.equals(s2));//false
    //equals源代码
    public boolean equals(Object obj) {
            return (this == obj);
        }
    
  • 方法覆盖五步骤

    • 快捷键:右键>Gennrate>equal
    @Override
        public boolean equals(Object o) {
            if (this == o) return true;//1、判断两个对象是否是同一个引用
           if (o == null || getClass() != o.getClass()) return false;//2、判断o是否为NULL3、判断是否是同一个类型
            Body body = (Body) o;//4、强制类型转换
            return age == body.age && Objects.equals(name, body.name);//5、判断属性
        }
            Body s3 = new Body("lvtu",15);
            System.out.println(s1.equals(s3));//true
    

5、finalize() 方法

作用:用于垃圾对象回收,由 JVM 自动调用,回收进队列

若想手动回收,需调用 System.gc() 方法,并通知 JVM 执行了垃圾回收(通过重载 finalize() 方法实现)

回收就一次,重复执行程序则不再出现结果

//源码
protected void finalize() throws Throwable { }
}
//重载
    @Override
    protected void finalize() throws Throwable {
        System.out.println(this.name+"对象被回收了");;
    }
    public static void main(String[] args) {

//        Body s1=new Body("lvtu",15);
//        Body s2=new Body("lvtu",16);
//        Body s3=new Body("lvtu",16);
//        Body s4=new Body("lvtu",16);

        new Body("lvtu", 15);//当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象
        new Body("lvtu", 16);
        new Body("lvtu", 16);
        new Body("lvtu", 16);
        System.gc();	
    }

7.3、包装类

基本数据类型 包装类型(引用类型)
btye Byte
shrot Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
String

1、类型转换

类型转换:基本类型 与 引用类型 的相互转换

JDK1.5 后,提供自动装箱和拆箱——反编译软件 XJad(分析.class文件)

🌻装箱
  • 基本类型转换为引用类型

  • 	int num=15;
        //自动装箱
        Integer integer1 = num;
        System.out.println(integer1);//15
    
🌻拆箱
  • 引用类型转换为基本类型

  •     //自动拆箱
        int age2 = integer1;
        System.out.println(age2);//15
    

反编译软件 XJad

  • 底层实现
  • valueof()/XXXValue() 方法
  • image-20220404113306487

2、基本类型与字符串间转换

parseXXX() 方法的使用

注意类型的匹配性 150——int

  • 基本类型 转化成 字符串类型

    • 	int n1 = 100;
      	String n2 = Integer.toString(n1);
      	System.out.println(n2);//100
      
  • 字符串类型 转换成 基本类型

    • 	String n3="150";
          int n4 = Integer.parseInt(n3);
          System.out.println(n4);//150
      

3、Integer缓冲区—IntegerCache

创建了一片 Integer 类型的数组

//valueOf()方法源码
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
🌻//IntegerCache源码
private static class IntegerCache {
        static final int low = -128;
        static final int high;//127
        static final Integer cache[];//数组
    {
        ...
    }

7.4、String类

1、字符串池存储原理

在方法区内常量池中,开辟空间用来存储字符串常量

  • 字符串常量特性

    • 不可变性——因为改变时要重写开辟空间
    • 共享性——地址共享
  • 另一种创建方式

    • String s = new String("Hello"),产生两个对象,堆、池中各存储一个
  • 用equals() 检验两个字符串是否相等

    image-20220405112954065

2、String 常用方法

调用源码去瞅瞅

  • 🌻完成对字符串的——查询

4、构建字符串 StringBuilder类

  • StringBuffer(是否是String的默认类?) :线程安全,但运行效率慢,是后者的前身
  • StringBuilder :线程不安全,但运行效率快
  • 三步骤:

    • //创建一个构建器
      StringBuilder builder = new StringBuilder;
      //调用append方法——拼接
      builder.append(ch);
      builder.append(str);
      //调用tostring方法输出
      System.out.println(builder.toString());
      
  • 方法

    • 🌻完成对字符串的——增删改

    • 	String name = "jiayou";
             //长度
             System.out.println(name.length());//6
             //返回某个位置的字符
             System.out.println(name.charAt(name.length()-1));//u
             //判断是否包含某个子串
             System.out.println(name.contains("jia"));//true
      
      • contains 方法源码好像被封装了

7.5、枚举类型

这篇文章绝了

定义

这是在没有枚举类型时定义常量常见的方式

/**
 * 使用普通方式定义日期常量
 */
public class DayDemo {

    public static final int MONDAY =1;

    public static final int TUESDAY=2;

    public static final int WEDNESDAY=3;

    public static final int THURSDAY=4;

    public static final int FRIDAY=5;

    public static final int SATURDAY=6;

    public static final int SUNDAY=7;

}

上述的常量定义常量的方式称为int枚举模式,这样的定义方式并没有什么错,但它存在许多不足,如在类型安全和使用方便性上并没有多少好处,如果存在定义int值相同的变量,混淆的几率还是很大的,编译器也不会提出任何警告,因此这种方式在枚举出现后并不提倡,现在我们利用枚举类型来重新定义上述的常量,同时也感受一把枚举定义的方式,如下定义周一到周日的常量

//枚举类型,使用关键字enum
enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

相当简洁,在定义枚举类型时我们使用的关键字是enum,与class关键字类似,只不过前者是定义枚举类型,后者是定义类类型。枚举类型Day中分别定义了从周一到周日的值,这里要注意,值一般是大写的字母,多个值之间以逗号分隔。同时我们应该知道的是枚举类型可以像类(class)类型一样,定义为一个单独的文件,当然也可以定义在其他类内部,更重要的是枚举常量在类型安全性和便捷性都很有保证,如果出现类型问题编译器也会提示我们改进,但务必记住枚举表示的类型其取值是必须有限的,也就是说每个值都是可以枚举出来的,比如上述描述的一周共有七天。那么该如何使用呢?如下:

/**
 * Created by zejian on 2017/5/7.
 * Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
 */
public class EnumDemo {

    public static void main(String[] args){
        //直接引用
        Day day =Day.MONDAY;
    }

}
//定义枚举类型
enum Day {
    MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

7.6、BigDecimal类(大数)

引言:二进制中的1/10,就好比十进制中的1/3,除不尽

double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1-d2);//0.09999999999999998

位置:Java.math 包

作用:精确计算浮点数

//创建+subtract方法
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
//减法
BigDecimal r1 = bd1.subtract(bd2);
System.out.println(r1);//0.1
//除法
BigDecimal r2 = bd1.divide(bd2,2,BigDecimal.ROUND_HALF_DOWN);//ROUND_HALF_DOWN 四舍五入
System.out.println(r2);//1.11
//divide 源码
public BigDecimal divide(BigDecimal divisor, int scale(小数位), int roundingMode(舍入模式)) 

7.7、时间日期类

1、Date 类

java.util.Date

好多方法都过时了

  • 常用方法
返回值类型 方法
boolean after(Date when) 测试此日期是否在指定日期之后。
boolean before(Date when) 测试此日期是否在指定日期之前。
int compareTo(Date anotherDate) 比较两个日期进行订购。
boolean equals(Object obj) 比较两个日期来平等。

2、🌻Calendar 类

  • 创建 Calendar 对象

    • 因为 Calendar 被protected 修饰,所以不能直接 New 对象
    //创建
    Calendar calendar = Calendar.getInstance();
    System.out.println(calendar.getTime().toLocaleString());//2022-4-9 10:47:28
    System.out.println(calendar.getTimeInMillis());//1649472593141——自1970年来的毫秒值
    

    image-20220409104125169

  • 方法

其他操作时间方法类似

//1、获取时间信息——年
int year = calendar.get(Calendar.YEAR);
System.out.println(year);//2022

//2、修改时间——日
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.DATE,5);//返回值类型 void
System.out.println(calendar1.getTime().toLocaleString());//2022-4-5 11:08:57
//3、抽象方法——add
Calendar calendar2 = Calendar.getInstance();
calendar1.add(Calendar.HOUR,-6);
System.out.println(calendar1.getTime().toLocaleString());//2022-4-5 5:13:07

3、SimpleDateFormat 类

java.text.Format 包

用于以区域设置敏感的方式格式化解析日期

//创建
SimpleDateFormat mat = new SimpleDateFormat("y/M/d H-m-s");//格式固定
//创建Date
 Date date = new Date();
//格式化——把日期转化为字符串
String str = mat.format(date);
System.out.println(str);// 2022/4/9 11-43-8
//解析——把字符串转化成时间
Date date1 = mat.parse("1990/9/8");//格式保存一致
System.out.println(date1);

7.8、System类

都是私有方法,所以不需要创建对象

  • 方法
		int[] arr = {20,51,54,66};
        int[] nss = new int[4];
        System.arraycopy(arr,0,nss,0,arr.length);
        //遍历
        for (int i = 0; i < nss.length; i++) {
            System.out.print(nss[i]);//20 51 54 66

八、集合类

  • 将接口看作一种类
    • 接口就是父类
    • 接口实现类就是子类
  • 集合只存储引用类型

image-20220412110809747

🌹集合中有两个基本接口——Collection 和 Map

  • 妈的!只吃现成的(调用),具体方法还得看子类(实现类)

8.1、Collection接口和实现类

java.util.* 包

  • 总体系继承关系结构
image-20220410092831111

1、Colletion 测试类

结合接口理解:

  • ArrayList、LinkedList... 看作子类
  • 常用方法 add、Iterator...在子类中已经实现
  • 我们只需要编写测试类
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class demo {
    public static void main(String[] args) {
        Collection collection = new ArrayList();
        Student stu = new Student();
        //1、添加元素
        collection.add("榴莲");
        collection.add("苹果");
        collection.add("香蕉");//字符串类型
        collection.add(stu);//引用类型
        //查看数量
        System.out.println(collection.size());//3
        //返回对象的字符串
        System.out.println(collection);//[榴莲, 苹果, 香蕉]
//      //2、删除元素
//      collection.remove("榴莲");
//      collection.clear();
        //3、遍历
        //3.1使用增强 for
        for (Object object:collection) {
            System.out.println(object);//榴莲, 苹果, 香蕉
        }
        System.out.println("----------");
        //3.2使用迭代器✨
        Iterator it = collection.iterator();
        while (it.hasNext())
        {
            System.out.println(it.next());//榴莲, 苹果, 香蕉
            //不允许使用collection,正在使用,不能删
            //collection.remove(s);
            it.remove();//删除
        }
        System.out.println(collection.size());
        //4、判断
        System.out.println(collection.contains("西瓜"));
    }
}
✨Collection迭代器 Iterator
  • 源码——三种方法
    • 与 API 一致
image-20220410110939434

8.2、List接口与实现类

List 作为 Collection 的子接口,功能更强大

特点:有序,有下标,元素可以重复

  • 单独看一看迭代器的区别(强大)

1、List 测试类

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class demo {
    public static void main(String[] args) {
        List<String> lines = new ArrayList<String>();
        lines.add("大象");
        lines.add("狼虎");
        lines.add("河马");
        //遍历——迭代器
        ListIterator<String> it = lines.listIterator();//<String>强制转换
        while(it.hasNext()) {   //顺序遍历
            System.out.println(it.nextIndex()+":"+it.next());//0:大象 1:狼虎 2:河马
        }
        while(it.hasPrevious()) {   //倒序遍历
            System.out.println(it.previousIndex()+":"+it.previous());//2:河马 0:大象 1:狼虎
        }

    }
}
✨List 迭代器 ListIterator
  • 源码——多种方法
image-20220412094748742

2、List 实现类

✨ArrayList 类

数组结构:顺序表

顺序表的增删改查通过调用 ArrayList 方法实现

  • 测试类

    • 需要重写 equals

      • equals 重写💖——不局限于remove方法

      • @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Student student = (Student) o;
                return age == student.age && Objects.equals(name, student.name);
            }
        
    • 需要重写 toString

      • @Override
            public String toString() {
                return "Student{" +
                        "age=" + age +
                        ", name='" + name + '\'' +
                        '}';
            }
        
import java.util.ArrayList;

public class demo {
    public static void main(String[] args) {
        ArrayList arr = new ArrayList();
        //创建对象
        Student s1 = new Student(12,"huaqiang");
        Student s2 = new Student(12,"lihua");
        Student s3 = new Student(12,"maoyu");
        //添加元素
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        System.out.println(arr.toString());
        //删除
        arr.remove(new Student(12,"lihua"));//equals 重写💖——不局限于remove方法
        System.out.println(arr.toString());//[Student{age=12, name='huaqiang'}, Student{age=12, name='maoyu'}]
        //遍历,判断,上同
    }
  • 源码

    • 创建集合(构造器)+add方法(两种)分析—扩容为原来的1.5 倍

    • 有空自己分析一遍

public class ArrayList<E> extends AbstractList<E>
    //默认容器
    private static final int DEFAULT_CAPACITY = 10;
	//用于默认大小的空实例的共享空数组实例
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
	//默认构造器
	public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
	🌻//add 方法源码分析——1
	public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
        🌻//ensureCapacityInternal 分析
        private static int calculateCapacity(Object[] elementData, int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            return minCapacity;
        }

        private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
        }

        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;

            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
        🌻//grow 扩容方法分析
            private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);// >>1 表示右移一位
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    
    🌻//add 方法源码分析——2
    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }
🌻LinkedList

数据结构:无头结点双链表尾插法

  • 测试类——上同

  • 源码

    • public class LinkedList<E>
          extends AbstractSequentialList<E>
          implements List<E>, Deque<E>, Cloneable, java.io.Serializable
      {
          transient int size = 0;
      
          transient Node<E> first;//头指针
      
          transient Node<E> last;//尾指针
          //Node<E>
          private static class Node<E> {
              E item;
              Node<E> next;
              Node<E> prev;
      
              Node(Node<E> prev, E element, Node<E> next) {
                  this.item = element;
                  this.next = next;
                  this.prev = prev;
              }
          }
          
          🌻add 方法分析
              public boolean add(E e) {
              linkLast(e);
              return true;
          }
          //linkLast(e);——无头结点双链表尾插法
          void linkLast(E e) {
              final Node<E> l = last;
              final Node<E> newNode = new Node<>(l, e, null);
              last = newNode;
              if (l == null)
                  first = newNode;
              else
                  l.next = newNode;
              size++;
              modCount++;
          }
      
🌻Vector

Java 1.0 开始使用

安全,但效率丢丢低

操作上同

  • ArrayList :数组结构,必须开辟连续空间,查询快,增删慢
  • LinkList :双向链表结构,无需开辟连续空间,查询慢,增删快

8.3、泛类与工具类

其本质上是参数化类型——把类型作为参数传递(基本类型+引用类型)

好处:泛型方法可以自行匹配数据类型,代替了方法重载

​ 防止类型转换异常,提高安全性

  • 语法

    • <E>——T表示类型占位符,表示一种引用类型(包装类)/其他类(例如:Student类)
          Elemtype
      

1、泛型类

  • 注意:泛型只能使用引用类型
public class Generic<T>{
        //1、创建变量,使用泛型T
        T t;
        //2、泛型作为方法的参数
        public void show(T t) {
            System.out.println(t);
        }
        //3、泛类作为方法的返回值
        public T shows(){
            return t;
        }
}

//测试类
public class demo {
    public static void main(String[] args) {
        Generic<String> gen = new Generic<>();//String类型

        gen.t = "lvtu";
        gen.show("jiayou");
        String str = gen.shows();//jiayou
        System.out.println(str);//lvyu

        Generic<Integer> gen2 = new Generic<>();//Integer类型
        //上同
        //Generic<String> gen3 = gen2;——报错
    }
}

2、泛型接口

  • 接口使用泛型

    • //接口
      public interface MyGeneric<T> {
          String name = "lvyu";
          T attack(T t);
      }
      //子类
      public class Generic implements MyGeneric<String> {
          @Override
          public String attack(String s) {
              System.out.println(s);
              return null;
          }
      }
      //实现类
      public class demo {
          public static void main(String[] args) {
              MyGeneric gen = new Generic();
              gen.attack("jiayou");
          }
      }
      
  • 接口和子类同时使用泛型

    • //接口
      public interface MyGeneric<T> {
          String name = "lvyu";
          T attack(T t);
      }
      //子类
      public class Generic<T> implements MyGeneric<T> {
          @Override
          public T attack(T t) {
              System.out.println(t);
              return null;
          }
      }
      //测试类
      public class demo {
          public static void main(String[] args) {
              MyGeneric<Integer> gen = new Generic();
              gen.attack(100);
          }
      }
      

3、泛型方法

与类/接口声明的位置不同

✨优势:调用改方法时,可以根据输入的数据类型,自行匹配引用类型

//泛类方法
public class Generic{
    public <T> T show(T t){
        System.out.println(t);
        return t;
    }
}
//测试类
public class demo {
    public static void main(String[] args) {
        Generic gen = new Generic();
        gen.show(100);
    }
}

4、泛型集合

语法:List lines = new ArrayList();//后面的可省略

编译时,即可查看压入的数据是否正确

  • ✨本质上是定义集合里面接口或类的类型

8.4、Set接口与实现类

Set 接口完全继承 Collection 接口中的方法

特点:无序、无下标,元素不可重复

1、Set 测试类

Set<String> set = new HashSet<>();
//增删改查
  • 其中迭代器依旧继承 Iterator

2、Set 实现类

✨HashSet 类

存储结构:哈希表(散列表)——数组+链表(孩子表示法)

无重复元素

  • 基本操作
//上同
🌹存储过程(元素重复依据)
  1. 根据 hashcode 计算保存位置,若此位置为空,则直接保存;否则执行下一步
  2. 再执行 equals 方法,若返回 true ,则认为重复,拒接存入;否则形成链表
//第一步 重写hashcode
@Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
	//底层源码
		public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }
//第二步 重写equals
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
//测试类
arr.add(new Student(12,"lihua"));//equals 重写💖——不局限于remove方法
🌻TreeSet 类

存储结构:红黑树

虽然无序,但是按照一定规律排序,无重复元素

  • 基本操作
//上同
1、元素排序Comparable 接口
  • 元素必须实现 Comparable 接口
    • 按照字母表顺序排序
//重写Comparable 接口
//将此对象与指定对象进行比较以进行排序。返回负整数、零或正整数,因为此对象小于、等于或大于指定对象。
public class Student implements Comparable<Student>{
    @Override
    public int compareTo(Student o) {
        int n1 = this.getName().compareTo(o.getName());//compareTo前后比较函数
        int n2 = this.age-o.getAge();
        return n1==0?n2:n1;
}
//测试类
import java.util.TreeSet;

public class demo {
    public static void main(String[] args) {
        TreeSet<Student> arr = new TreeSet<>();
        //创建对象
        Student s1 = new Student(12,"bff");
        Student s2 = new Student(12,"zll");
        Student s3 = new Student(12,"maoyu");
        //添加元素
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        System.out.println(arr.toString());//[Student{age=12, name='bff'}, Student{age=12, name='maoyu'}, Student{age=12, name='zll'}]
        //删除
        arr.remove(new Student(12,"zll"));//equals 重写💖——不局限于remove方法
        System.out.println(arr.toString());

    }
}
2、Comparator 接口

使用匿名内部类——优点:减少代码量

  • 在测试类中自己定制排序规则

8.5、Map接口与实现类

特点:1、用于存储 键值对(Key-Value)

​ 2、键:无序、无下标,不允许重复(唯一)

​ 3、值:无序、无下标,允许重复

image-20220417110729945

1、Map 测试类

九、IO

input/output

9.1、流的分类

内存与硬盘(C盘)之间传输数据的通道

9.2、字节流

9.3、编码方式

9.4、字符流

9.5、File类

十、JAVA 8

10.1《JAVA 8》目录

第一部分 基础知识

  • 第 1 章 为什么要关心 Java 8

  • 第 2 章 通过行为参数化传递代码

  • 第 3 章 Lambda 表达式

第二部分 函数式数据处理

  • 第 4 章 引入流
  • 第 5 章 使用流
  • 第 6 章 用流收集数据
  • 第 7 章 并行数据处理与性能

第三部分 高效Java 8编程

  • 第 8 章 重构、测试和调试
  • 第 9 章 默认方法
  • 第 10 章 用 Optional 取代 null
  • 第 11 章 CompletableFuture:组合式异步编程
  • 第 12 章 新的日期和时间 API

第四部分 超越Java 8

  • 第 13 章 函数式的思考

  • 第 14 章 函数式编程的技巧

  • 第 15 章 面向对象和函数式编程的混合:Java 8 和 Scala 的比较

  • 第 16 章 结论以及 Java 的未来

十一、GUI

核心技术:Swing、AWT

  • 不流行原因

    • 界面不美观,没 C+ +强
    • 需要 jre(java运行环境),占内存
  • 学习目的

    • 可以练手和制作小工具

1、AWT

该包下含有许多类和接口

底层逻辑:窗口—面板—(按钮、文本框、标签)

image-20220316083748838

🌻 Frame 窗口

  • 第一个窗口
package com.GUI界面编程;

import java.awt.*;

public class TestFrame {
    public static void main(String[] args) {
        Frame frame = new Frame("lvtu");
        //显示窗口
        frame.setVisible(true);
        //大小
        frame.setSize(400,400);
        //颜色
        frame.setBackground(Color.black);
        //位置
        frame.setLocation(200,200);
    }
}

image-20220316093558293

  • 多个窗口

    • 计算器
    • 封装

    image-20220316102621982

🌻 Panel 面板讲解

可以看成空间,但不能单独存在——结合窗口使用

image-20220316115538861

image-20220316115743474

🌻 三种布局管理器

创建按钮对象+调用 add 方法

三种布局的嵌套组合!——6、课堂练习视频

  • 流式布局 Flowlayout

  • 东西南北中 Borderlayout

  • 表格布局 GridLayout

🌻事件监听

2、Swing

十一、设计模式

posted @ 2022-04-17 11:30  坚持100天8/3  阅读(56)  评论(0)    收藏  举报