Java基础笔记

Java入门

1、Java三大版本

  1. JavaSE:标准版(桌面程序、控制台开发)
  2. JavaME:嵌入式开发(手机、小家电)
  3. JavaEE:E企业开发(web端、服务器开发)

2、JDK、JRE、JVM

  1. JDK:Java Development Kit
  2. JRE:Java Runtime Environment
  3. JVM:Java Virtual Machine
  4. JDK = JRE + Java开发工具(javac.exe、java.exe、javadoc.exe)
  5. JRE = JVM + Java核心类库(JavaSE标准库)
    在这里插入图片描述

3、JDK的卸载与安装

  1. JDK的卸载
    1. 删除Java安装目录
    2. 删除JAVA_HOME
    3. 删除path下关于Java的目录
    4. cmd 中输入 java-version 检测
  2. JDK的安装
    1. 百度搜索JDK8,找到下载地址
    2. 同意协议
    3. 下载电脑对应的版本
    4. 双击安装JDK
    5. 记住安装路径
    6. 配置环境变量
      7. JAVA_HOME jdk安装路径
      8. path %JAVA_HOME%\bin %JAVA_HOME%\jre\bin
    7. cmd 中输入 java-version 检测

4、Hello World

  1. 新建一个Java文件 Hello.java

  2. 编写代码

    public class Hello{
    	public static void main(String[] args){
    		System.out.print("Hello World");
    	}
    }
    
  3. 编译Hello.java

    1. 在Hello.java文件夹路径中输入cmd
    2. cmd窗口中输入 javac Hello.java
    3. 会生成一个Hello.class的class文件
  4. 运行Hello.class

    1. cmd窗口中输入 java Hello
    2. 会打印出java文件的内容 Hello World
  5. 注意

    1. 文件名和类名必须保证一致,且首字母大写
    2. Java大小写敏感

5、Java运行机制

  1. 编译型:将源代码一次性转换成目标代码的过程

    1. 编译器:执行辨析程序的过程
      在这里插入图片描述
  2. 解释型:将源代码逐条转换成目标代码同时逐条运行的过程

    1. 解释器:执行编译程序的过程
      在这里插入图片描述
  3. 编译和解释的区别

    1. 编译:一次性翻译,之后不再需要源代码(类似于英文翻译)
    2. 解释:每次程序运行时随翻译随执行(类似于英文中实时同声翻译)
  4. Java运行机制
    在这里插入图片描述

6、IDE

  1. 集成开发环境
  2. 是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。
  3. 集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。

Java基础

1、注释

  1. 注释不会被执行
  2. 注释有三种
    1. 单行注释:注释一行 //
    2. 多行注释:注释多行 /* */
    3. 文档注释:JavaDoc搭配使用 /** /
      1. javadoc命令是用来生成字节API文档的
        1. @author 作者名
        2. @version 版本号
        3. @since 指明需要最早使用的jdk版本
        4. @param 参数名
        5. @return 返回值情况
        6. @throws 异常抛出情况
      2. cmd命令:javadoc -encoding UTF-8 -charset UTF-8 -d newFileName myJavaFile.java
      3. IDEA操作:
        1. 打开 Tools -> GenerateJavaDoc 进行配置
        2. 在这里插入图片描述

2、标识符

  1. 关键字:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)

    Java关键字
    用于定义数据类型的关键字classinterfaceenumbyteshort
    intlongfloatdoublechar
    booleanvoid
    用于定义流程控制的关键字ifelseswitchcasedefault
    whiledoforbreakcontinue
    return
    用于定义访问修饰符的关键字privateprotectedpublic
    用于定义类、函数、变量修饰的关键字abstractfinalstaticsynchronized
    用于定义类与类之间的关键字extendsimplements
    用于定义建立实例以及引用实例,判断实例的关键字newthissuperinstanceof
    用于异常处理的关键字trycatchfinallythrowthrows
    用于包的关键字packageimport
    其他修饰符关键字nativestrictfptransientvolatileassert
    用于定义数据类型值的字面值truefalsenull
  2. 保留字:现在Java版本尚未使用,但以后版本可能作为关键字使用

    ​ goto、const避免,因为以后版本可能变成关键字使用

  3. 注意

    1. 所有标识符都应该以大小写字母、美元符号($)、下划线(_)开始
    2. 首字母之后可以是大小写字母、美元符号($)、下划线(_)、数字、中文等
    3. 不能使用关键字作为变量名或方法名
    4. 标识符大小写敏感
    5. 可以使用中文命名,不建议,也不建议使用拼音
    6. 标识符不能包含空格
  4. Java 所有的组成部分都需要名字。 类名、变量名、方法名都被成为标识符

3、数据类型

  1. 强类型语言:要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用 (Java)

  2. 弱类型语言:变量可以不严格符合规定 (Javascript)

  3. Java的数据类型

    1. 基本类型

      1. 数值类型

        1. 整数类型(默认值为0

          1. byte(占1个字节范围):-128 ~ 127
          2. short(占2个字节范围):-3,2768 ~ 3,2767
          3. int(占4个字节范围):-21,4748,3648 ~ 21,4748,3647(最常用)
          4. long(占8个字节范围):-922,3372,0368,5477,5808~ 922,3372,0368,5477,5807(Long类型要在数字后面加 L
        2. 浮点类型(默认值为0.0

          1. float(占4个字节范围)( Float 类型要在数字后面加 F
          2. double(占8个字节范围)(常用)
        3. 字符类型(默认值为

          ​ char:(占2个字节范围)(只包含一个字符

      2. 布尔类型:(默认值为false

        1. boolean:(占一位,值只有true和false
    2. 引用类型

      1. ​ String(字符串类型)(默认值为null

      2. 接口

      3. 数组

    3. 拓展:

      1. 浮点数

        1. float 有限 离散 接近但不等于
        2. BigDecimal 数学公式类
        3. 最好使用完全浮点数进行比较
      2. 字符

        1. 所有的字符本质还是数字
        2. Unicode编码(97=a,65=A)
        3. \u0061 表示 a
      3. 转义字符

        1. \t 制表符
        2. \n 换行符
        3. \b 退格符
        4. \ \ 反斜杠
      4. // 数据类型
        public class Demo03 {
            public static void main(String[] args) {
                
                /*
                浮点数拓展  银行业务如何表示?钱?
                BigDecimal 数学公式类
                float  有限 离散 接近但不等于
                最好完全使用浮点数进行比较
                 */
        
                float f = 0.1f;
                double d = 0.1;
                System.out.println(f==d); // false
        
                float f1 = 1232343554353f;
                float f2 = f1 + 1;
                System.out.println(f1 == f2); // true
        
                /*
                字符拓展
                所有的字符本质还是数字
                Unicode编码(97 = a 65 = A) 2字节
                 */
        
                char c1 = 'a';
                char c2 = '中';
        
                System.out.println(c1); // a
                System.out.println((int)c1); // 97
                System.out.println(c2); // 中
                System.out.println((int)c2); // 20013
        
                char c3 = '\u0061';
                System.out.println(c3); // a
        
                /*
                转义字符
                \t 制表符
                \n 换行符
                 */
                System.out.println("Hello\tWorld"); // Hello    World
        
                // 对象 从内存分析
                String sa = new String("hello world");
                String sb = new String("hello world");
                System.out.println(sa == sb); // false
        
                String sc = "hello world";
                String sd = "hello world";
                System.out.println(sc == sd); // true
        
                // 布尔值扩展
                boolean flag = true;
        
                if(flag==true){ } //新手
                if(flag){} //老手  代码要简洁
        
            }
        }
        
        

4、字节

  1. 位(bit):计算机内部数据最小储存单位,11001100是一个八位二进制数
  2. 字节(byte):是计算机中数据处理的基本单位,习惯上用B表示
  3. 1B = 8bit 即一个字节=8位
  4. 字符:计算机中使用的字符、数字、字、符号
  5. 常见
    1. 1bit 表示一位
    2. 1Byte表示一个字节 1B = 8b
    3. 1024B = 1KB
    4. 1024KB = 1M
    5. 1024M = 1G

5、进制

  1. 二进制:0,1 满2进1,以0b0B开头表示

  2. 十进制:0-9 满10进1

  3. 八进制:0-7 满8进1,以0开头表示

  4. 十六进制:0-9,A-F 满16进1,以0x0X表示

  5. // 进制
    public class Demo03 {
        public static void main(String[] args) {
            
            int i1 = 0b10; // 二进制0b
            int i2 = 10; // 十进制
            int i3 = 010; // 八进制0
            int i4 = 0x10; // 十六进制0x    0~9 A~F
    
            System.out.println(i1); // 2
            System.out.println(i2); // 10
            System.out.println(i3); // 8
            System.out.println(i4); // 16
    
        }
    }
    ~~~
    
    

6、类型转换

  1. byte,short,char -> int -> long -> float -> double (从低到高)

  2. 强制类型转换(高->低)

    1. (类型)变量名
    2. 需要使用强转符:()
    3. 注意:强制类型转换,可能导致内存溢出或精度损失
  3. 自动转换(低->高)

    1. 容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型
    2. 说明:此时的容量大指的是,表示数的范围的大和小。比如:float容量要大于long的容量
    3. 特别的:当byte 、char、short 三种类型的变量做运算时,结果为int型
  4. 注意:

    1. 不能对布尔值进行转换
    2. 不能把对象类型转换成不相干的类型
  5. // 类型转换
    public class Demo04 {
        public static void main(String[] args) {
            
            int i = 128;
            byte b = (byte)i; // 内存溢出 超过byte最大范围
            double d = i;
            char c = 'a';
            int num = c + 1;
    
            System.out.println(i); // 128
            System.out.println(b); // -128
            System.out.println(d); // 128.0
            System.out.println((int)28.7); // 28
            System.out.println((int)-45.6f); // -45
            System.out.println(num); // 98
            System.out.println((char)num); // b
        }
    }
    
  6. // 乘法运算中的内存溢出问题
    public class Demo06 {
        public static void main(String[] args) {
            // 操作数比较大的数的时候,注意溢出问题
            // JDK7新特性,数字之间可以用下划线分割
            int money = 10_0000_0000;
            int years = 20;
            int total = money * years;
            long total2 = money * years;
            long total3 = money * (long)years; // 先把一个数转换成long
    
            System.out.println(total); // -1474836480,计算的时候溢出了  int类型最大21亿多
            System.out.println(total2); // -1474836480,默认是int,转换之前就溢出了
            System.out.println(total3); // 20000000000
    
            // L l (小写容易看成1,最好大写)
        }
    }
    

7、变量

  1. Java变量是程序中最基本的存储单元,要素:变量名、变量类型、作用域

  2. 数据类型 变量名 = 值 ; (可以用逗号隔开来声明多个同类型变量)

  3. 注意:

    1. 每个变量都有类型,类型可以是基本类型,也可以是引用类型
    2. 变量名必须是合法字符
    3. 变量声明是一条完整的语句,因此每一个声明都以分号结束
    4. 变量必须先声明后使用
  4. 变量作用域

    1. 成员变量:在方法体外,类体内声明的变量

      1. 实例变量(不以static修饰)
      2. 类变量(以static修饰)
    2. 局部变量:方法体内声明的变量

      1. 形参(方法、构造器中定义的变量)
      2. 方法局部变量(在方法内定义)
      3. 代码块局部变量(在代码块内定义)
    3. 成员变量与局部变量的区别

      1. 在类中位置不同

        1. 成员变量:在方法体外,类体内声明的变量
        2. 局部变量:方法体内声明的变量
      2. 在内存中的位置不同

        1. 成员变量:在堆中
        2. 局部变量:在栈中
      3. 生命周期不同

        1. 成员变量:随着对象的创建而存在,随着对象的消失而消失
        2. 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
      4. 初始值

        1. 成员变量:有默认初始值
        2. 局部变量:没有默认初始值,使用之前需要赋值
      5. this

        1. 当局部变量与全局变量同名时,局部覆盖全局
        2. 如果一定要使用全局变量,则加前缀this.(当前对象)
      6. // 成员变量与局部变量
        public class Demo01 {
            static String name; // 成员变量 不赋值有默认初始值
            static String school = "成员变量";
        
            public static void main(String[] args) {
                System.out.println(school); // 成员变量
                System.out.println(name); // null
                new Demo01().show(); // 局部变量
                new Demo01().test(1, 2); // 1 \n 2
            }
        
            public void test(int a , int b){ // 局部变量
                System.out.println(a); // 1
                System.out.println(b); // 2
            }
        
            public void show(){
                String name = "局部变量";
                String school;
        //        System.out.println(school);  // 未初始化变量school 报错
                System.out.println(this.school); // 成员变量    就近原则
                System.out.println(name); // 局部变量
            }
        }
        
  5. 常量

    1. 常量:初始化后不能再改变值!
    2. 常量名一般大写
    3. final 变量名 = 值
    4. final double PI = 3.14
  6. 变量的命名规范

    1. 包名:xxxyyyzzz
    2. 类名、接口名:XxxYyyZzz
    3. 变量名、方法名:xxxYyyZzz 、xxxYyyZzz()
    4. 常量名:XXX_YYY_ZZZ
    5. 命名要”见名知意“

8、运算符

  1. 算术运算符:+、-、*、/、%、++、–

  2. 赋值运算符:=

  3. 关系运算符:>、<、>=、<=、==、!=、instanceof(检测是否是类的对象)

  4. 逻辑运算符:&、|、!、^、&&(短路与)、||(短路或)

  5. 位运算符(直接是对整数的二进制进行的计算):&、|、^、~、<<、>>、>>>

    1. 2<<3 = 8 12>>2 = 3
    2. 左移( << ):空位补0,被移除的最高位丢弃,空缺位补0。相当于 *2
    3. 右移( >> ):被移动的二进制最高位是0,右移后,空缺位补0;;最高位是1,空缺位补1.相当于 /2
    4. 无符号右移( >>> ):被移动的二进制最高位无论是0或者是1,空缺位都用0补
    5. 取反运算( ~ ):各二进制码按补码各位取反
      1. 正数 原码 = 反码 = 补码
      2. 负数 反码 = 原码取反(最高位不变,其他位取反) 补码 = 反码 + 1
  6. 条件运算符:? :

    ​ x ? y : z (如果x=true,则结果为y,否则结果为z)

  7. 扩展赋值运算符:+=、-=、*=、/=

9、包机制

  1. 为了更好地组织类,Java 提供了包机制,用于区别命名空间
  2. 一般用公司域名导致作为包名
  3. 百度:www.baidu.com 包名:com.baidu.www

Java流程控制

1、Scanner对象

  1. 可以通过 Scanner 类来获取用户的输入
  2. 基本语法:Scanner s = new Scanner(System.in);
  3. 可以通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串
  4. 读取之前,可以通过 hasNext() 与 hasNextLine() 判断是否还有输入的数据
  5. next() 与 nextLine()
    1. next():
      1. 一定要读取到有效字符后才可以结束输入
      2. 对输入有效字符之前遇到的空白,next()方法会自动将其去掉
      3. 只有输入有效字符后才将其后面输入的空白作为分隔符或结束符
      4. next() 不能得到带有空格的字符串
    2. nextLine():
      1. 以Enter 为结束符,也就是说nextLine() 方法返回的是回车之前的所有字符(包括前面的空格)
      2. 可以获得空白

2、顺序结构

  1. Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
  2. 语句与语句之间,框与框之间都是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的
  3. 它是任何一个算法都离不开的一种基本算法结构

3、选择结构

  1. if 单选择结构

    ​ if (布尔表达式) { 如果布尔表达式为 true 将执行的代码 }

  2. if 双选择结构

    ​ if (布尔表达式) { 如果布尔表达式为 true 将执行的代码 } else { 如果布尔表达式为 false 将执行的代码 }

  3. if 多选择结构

    ​ if (布尔表达式1) { 如果布尔表达式1为 true 将执行的代码} else if ( 布尔表达式2 ) { 如果布尔表达式2为 true将执行的代码} else { 如果以上表达式都不为 true 执行的代码}

  4. 嵌套的if结构

    ​ if (布尔表达式1) { 如果布尔表达式1为 true 将执行的代码 if (布尔表达式2) { 如果布尔表达式2为 true 将执行的代码 } }

  5. switch多选择结构

    1. switch case 语句判断一个变量与一系列值中某个值是否相等,每一个值称为一个分支
    2. switch 语句中的变量类型可以是:byte、short、int、char、String
    3. case 标签必须为字符串常量或字面量
    4. switch (expression){ case value1: 语句1; break //可选; case value2: 语句2; break; case value3: 语句3; break; default: 语句; }

4、循环结构

  1. while循环

    1. while( 布尔表达式 ) { //如果布尔表达式为 true 将执行的代码 }
    2. 我们大多数情况会让循环停止下来,我们需要一个表达式失效的方式来结束循环
  2. do … while循环

    1. 相对于while循环而言,但do…while循环至少会执行一次
    2. 区别:
      1. while先判断后执行,do … while是先执行后判断
      2. do … while总是抱着循环体会被至少执行一次
  3. for 循环

    1. for (初始化; 布尔表达式; 更新){ // 代码语句 }

    2. 增强for循环

      1. for (声明语句:表达式){ // 代码 }

      2. 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

      3. 表达式:表达式是要访问的数组名,或者是返回值为数组的方法

      4. 打印三角形

        // 打印5行的三角形
        public class TestDemo {
            public static void main(String[] args) {
                for (int i = 0; i < 5; i++) {
                    for (int z = 5; z > i; z--) {
                        System.out.print(" ");
                    }
                    for (int x = 0; x <= i; x++) {
                        System.out.print("*");
                    }
                    for (int j = 0; j < i; j++) {
                        System.out.print("*");
                    }
                    System.out.println();
                }
            }
        }
        
      5. DeBug调试:通过打断点来查看代码执行过程

5、break continue

  1. break:用于强制退出循环,不执行循环中剩余的语句

  2. continue:用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定

  3. 区别:

    break与continue区别
    breakswitch-case、循环结构结束当前循环关键字后面不能声明执行语句
    continue循环结构结束当次循环关键字后面不能声明执行语句
    return结束方法,返回一个结果关键字后面不能声明执行语句
  4. 关于goto关键字(不建议)

    1. 在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子—带标签的break和continue
    2. 对Java来说唯一用到标签的地方是在循环语句之前。

Java方法

1、何谓方法

  1. Java方法是语句的集合,它们在一起执行一个功能
    1. 方法是解决一类问题的步骤的有序组合
    2. 方法包含于类或对象中
    3. 方法在程序中被创建,在其他地方被引用
  2. 设计方法的原则
    1. 方法的本意是功能块,就是实现某个功能的语句块的集合。
    2. 设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样利于我们后期的扩展
  3. Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
    1. 方法 = 方法头 + 方法体
    2. 修饰符 返回值类型 方法名 ( 参数类型 参数名 ){ 方法体 return 返回值; }
    3. 方法的所有部分:
      1. 修饰符:可选的,告诉编译器如何调用该方法,定义了该方法的访问类型
      2. 返回值类型:方法可能会返回值,returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
      3. 方法名:是方法的实际名称。方法名和参数共同构成方法签名。
      4. 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
        1. 形式参数:在方法被调用时用于接收外界输入的数据
        2. 实参:调用方法时实际传给方法的数据
      5. 方法体:方法体包含具体的语句,定义该方法的功能

2、方法调用

  1. 调用方法:对象名 . 方法名(实参列表)
  2. Java支持两种调用方法的方式,根据方法是否返回值来选择。
  3. 当方法返回一个值的时候,方法通用通常被当作一个值。 int large = max(30, 40)
  4. 如果方法返回值是void,方法调用一定是一条语句。 System.out .println(" hello world")
  5. Java都是值传递
    1. 值传递:是指在调用函数时将实际参数复制一份传递到参数中,这样在函数中如果对参数进行修改,将不会影响到实际参数
    2. 引用传递:是指在调用函数将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数

3、方法重载

  1. 重载就是在一个类中,有相同的函数名称,但形参不同的函数
  2. 方法的重载的规则:
    1. 方法名称必须相同
    2. 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同)
    3. 方法的返回类型可以相同也可以不同
    4. 仅仅返回类型不同不足以成为方法的重载
  3. 实现理论:方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错

4、命令行传参

​ 有时候你希望运行一个程序的时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

5、可变参数

  1. Java支持传递同类型的可变参数给一个方法
  2. 在方法声明中,在指定参数类型后加一个省略号(…)
  3. 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它声明之前

6、递归

  1. 递归:自己调用自己
  2. 利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合
  3. 递归结构:
    1. 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环
    2. 递归体:什么时候需要调用自身方法

Java数组

1、数组概述

  1. 数组是相同类型数据的有序集合
  2. 数组描述的是相同类型的若干个数组,按照一定的先后次数排列组合而成
  3. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们

2、数组声明创建

  1. 首先必须声明数组变量,才能在程序中使用数组。语法:

    1. dataType[ ] arrayRefVar ; // 首选的方法
    2. dataType arrayRefVar[ ]; // 效果相同,但不是首选方法
  2. Java语言使用new操作符来创建数组,语法:

    1. dataType[ ] arrayRefVar = new dataType[ arraySize ];
  3. 数组的元素是通过索引访问的,数组索引从0开始

  4. 获取数组长度:array.length

  5. 数组的四个基本特点

    1. 其长度是确定的,数组一旦被创建,它的大小就是不可以改变的
    2. 其元素必须是相同类型,不允许出现混合类型
    3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型
    4. 数组变量属于引用变量,数组可以看作是对象,数组中的每个元素相当于该对象的成员变量
    5. 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身就是在堆里
  6. 内存分析
    在这里插入图片描述

  7. 创建数组
    在这里插入图片描述

  8. 数组边界:

    1. 下标的合法区间:[0, length - 1],如果越界就会报错
    public static void main(String[] args){
        int[] a = new int[2];
        System.out.println(a[2]);
    }
    
    1. ArrayIndexOutOfBoundsException:数组下标越界异常
  9. 三种初始化

    1. 静态初始化
    int[] a = {1, 2 ,3};
    Man[] mans = {new Man(1, 1),new Man(2, 2)};
    
    1. 动态初始化
    int[] a = new int[2];
    a[0] = 1;
    a[1] = 2;
    
    1. 数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
  10. 小结

    1. 数组是相同数据类型(数据类型可以为任何类型)的有序集合
    2. 数组也是对象。数组元素相当于对象的成员变量
    3. 数组长度是确定的,不可变的。如果越界,则报:ArrayIndexOutOfBoundsException

3、数组的使用

  1. 普通的For循环

  2. For—Each循环

  3. 数组作方法入参

  4. 数组作返回值

    // 数组的使用
    public class ArrayDemo04 {
        public static void main(String[] args) {
            // JDK1.5,没有下标
            int[] arrays = {1, 3, 4, 5, 2};
    
            // For-Each 打印
            for (int array : arrays) {
                System.out.println(array);
            }
    
            printArray(arrays);
            int[] reverse = reverse(arrays);
            printArray(reverse);
        }
    
        // 打印数组元素
        public static void printArray(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
        }
    
        // 反转数组
        public static int[] reverse(int[] arr){
            int[] result = new int[arr.length];
    
            // 反转的操作
            for (int i = 0, j = arr.length-1; i < arr.length; i++, j--) {
                result[i] = arr[j];
            }
            return result;
        }
    }
    
    

4、多维数组

  1. 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组

  2. 二维数组

    int a[][] = new int[3][5];
    

    解析:以上二维数组a可以看成一个三行五列的数组
    在这里插入图片描述

    // 二维数组
    public class ArrayDemo05 {
        public static void main(String[] args) {
            // 定义一个四行两列的数组  [4][2]
            /*
                1,2   array[0]
                3,4   array[1]
                5,6   array[2]
                7,8   array[3]
             */
            int[][] array = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
    
            for (int arr : array[0]) {
                System.out.print(arr + " "); // 1 2
            }
            System.out.println("------------------------------");
            printArray(array[0]); // 1 2
            System.out.println("------------------------------");
            System.out.println(array[0][0]);  // 1
            System.out.println(array[0][1]);  // 2
    
            System.out.println(array.length); // 4
            System.out.println(array[0].length); // 2
    
            System.out.println("---------------------------------");
            printTwoArray(array); // 1 2 3 4 5 6 7 8
        }
    
        // 打印数组元素
        public static void printArray(int[] arr) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
        }
    
        // 打印二维数组所有元素
        public static void printTwoArray(int[][] arr){
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
            }
        }
    }
    
    

5、Arrays 类

  1. 数组的工具类java.util.Arrays
  2. 由于数组对象本身并没有什么方法可以提供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
  3. 查看JDK帮助文档
  4. IDEA中 ctrl + Arrays 打开 Arrays源码 打开IDEA的 Structure 看到Arrays的所有方法
  5. Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用**(注意:是“不用”而不是“不能”)**
  6. 常用功能
    1. 给数组赋值:通过fill方法
    2. 对数组排序:通过sort方法,按升序
    3. 比较数组:通过equals方法比较数组中元素值是否相等
    4. 查找数组元素:通过binarySearch方法对排序好的数组进行二分查找法操作
  7. 冒泡排序
    1. 总共有八大排序
    2. 两层循环,外层冒泡轮数,里层一次比较
    3. 时间复杂度:O( n^2)
      public class ArrayDemo07 {
          public static void main(String[] args) {
      
              int[] a = {2, 3, 532, 234, 43, 234};
              int[] sort = sort(a); // 调用完我们自己写的排序方法以后,返回一个排序后的数组
              System.out.println(Arrays.toString(sort));
          }
      
      
          // 冒泡排序
          /*
          1、比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
          2、每一次比较,都会产生出一个最大,或者最小的数字
          3、下一轮则可以少一次排序
          4、依次循环,直到结束
           */
      
          public static int[] sort(int[] arr) {
              // 临时变量
              int temp = 0;
              // 外层循环,判断我们这个循环走多少次
              for (int i = 0; i < arr.length; i++) {
                  boolean flag = false; // 通过flag标识位减少没有意义的比较
      
                  // 内存循环,如果第一个数比第二个数大,则交换位置
                  for (int j = 0; j < arr.length - i - 1; j++) {
                      if (arr[j + 1] > arr[j]) {
                          temp = arr[j];
                          arr[j] = arr[j + 1];
                          arr[j + 1] = temp;
                          flag = true;
                      }
                  }
                  if (flag = false) {
                      break;
                  }
              }
              return arr;
          }
      }
      

6、稀疏数组

  1. 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。

  2. 稀疏数组的处理方式:

    1. 记录数组一共有几行几列,有多少个不同值
    2. 把记录不同值的元素和行列及值记录在要给小规模的数组中,从而缩小程序的规模
  3. 左边是原始数组,右边是稀疏数组
    在这里插入图片描述

    // 稀疏数组
    public class ArrayDemo08 {
        public static void main(String[] args) {
            // 创建一个二维数组array1[11][11]   0:没有棋子   1:黑棋  2:白棋
            int[][] array1 = new int[11][11];
            array1[1][2] = 1;
            array1[2][3] = 2;
    
            // 输出原始的数组
            System.out.println("输出原始的数组");
            for (int[] ints : array1) {
                for (int anInt : ints) {
                    System.out.print(anInt + "\t");
                }
                System.out.println();
            }
    
            // 转换为稀疏数组
    
            // 获取有效值的个数
            int sum = 0;
            for (int i = 0; i < 11; i++) {
                for (int j = 0; j < 11; j++) {
                    if(array1[i][j] != 0){
                        sum++;
                    }
                }
            }
            System.out.println("有效值的个数"+sum);
    
            // 2、创建一个稀疏数组的数组
            int[][] array2 = new int[sum+1][3];
            array2[0][0] = 11;
            array2[0][1] = 11;
            array2[0][2] = sum;
    
            // 遍历二维数组,将非零的值存放到稀疏数组中
            int count = 0;
            for (int i = 0; i < array1.length; i++) {
                for (int j = 0; j < array1[i].length; j++) {
                    if(array1[i][j] != 0){
                        count++;
                        array2[count][0] = i;
                        array2[count][1] = j;
                        array2[count][2] = array1[i][j];
                    }
                }
            }
    
            System.out.println("稀疏数组");
            for (int i = 0; i < array2.length; i++) {
                System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
            }
    
            System.out.println("-------------------------------");
            System.out.println("还原");
    
            // 1、读取稀疏数组
            int[][] array3 = new int[array2[0][0]][array2[0][1]];
    
            // 2、给其中的元素还原它的值
            for (int i = 1; i < array2.length; i++) {
                array3[array2[i][0]][array2[i][1]] = array2[i][2];
            }
    
            // 3、打印
    
            System.out.println("输出还原的数组");
            for (int[] ints : array1) {
                for (int anInt : ints) {
                    System.out.print(anInt + "\t");
                }
                System.out.println();
            }
    
        }
    }
    

面向对象编程

1、初识面向对象

  1. 面向过程与面向对象
    1. 面向过程思想
      1. 步骤清晰,第一步做什么,第二步做什么
      2. 面向过程适合做一些较为简单的问题
    2. 面向对象思想
      1. 物以类聚,分类的思维模式,思考问题首选会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对分类下的细节进行面向过程的思索
      2. 面向对象时候处理复杂的问题,适合处理需要更多人协作的问题
    3. 对于描述复杂的事务,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理
  2. 什么是面向对象
    1. 面向对象编程(Object-Oriented Programming,OOP)
    2. 面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据
    3. 抽象
    4. 三大特性:
      1. 封装
      2. 继承
      3. 多态
    5. 从认识论角度考虑是先有对象后有类。对象,是具体的事务。类,是抽象的,是对对象的抽象
    6. 从代码运行角度考虑是先有类后有对象。类是对象的模板

2、对象的创建分析

  1. 类和对象的关系

    1. 类是一种抽象的数据类型,它是对某一类事物整体描述/ 定义,但是并不能代表某一个具体的事务

      ​ Person类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为

    2. 对象是抽象概念的具体实例

      ​ 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例

      ​ 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念

  2. 创建与初始化对象

    1. 使用new关键字创建对象

    2. 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用

    3. 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点

      1. 必须和类的名字相同
      2. 必须没有返回类型,也不能写void
    4. 构造器

      1. 特点:
        1. 和类名相同
        2. 没有返回值
      2. 作用:
        1. new本质在调用构造方法
        2. 初始化对象的值
      3. 注意:定义了有参构造之后,如果想使用无参构造,显示一个无参构造
    5. 创建对象内存分析
      在这里插入图片描述

  3. 小结:

    1. 类与对象:类是一个模板:抽象,对象是一个具体的实例
    2. 方法:定义、调用
    3. 对象的引用
      1. 引用类型: 基本类型(8)之外的
      2. 对象是通过引用来操作的,栈—>堆
    4. 属性:字段Field 成员变量
      1. 默认初始化
      2. 修饰符 属性类型 属性名= 属性值
    5. 对象的创建和使用
      1. 必须使用new关键字创造对象,构造器
      2. 对象的属性
      1. 静态的属性 属性
      2. 动态的行为 方法

3、面向对象的三大特性

  1. 封装

    1. 属性私有,get / set
    2. 封装(数据的隐藏):禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
    3. 作用
      1. 提高程序的安全性
      2. 隐藏代码的实现细节
      3. 统一接口
      4. 系统可维护性增加
  2. 继承

    1. 继承

      1. 继承的本质是堆某一批类的抽象,从而实现对现实世界更好的建模
      2. extends 是“扩展”。子类是父类的扩展
      3. Java中类只有单继承,没有多继承
      4. 继承是类和类之间的关系。关系还有依赖、组合、聚合
      5. 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,用extends表示。
      6. 子类和父类之间是“is a ”的关系。例如:学生是一个人
    2. object类

      ​ 在Java中,所有的类,都默认直接或者间接继承Object类

    3. super

      1. super调用父类的构造方法,必须在构造方法的第一个
      2. super必须只能出现在子类的方法或者构造方法中
      3. super 和 this不能同时调用构造方法
      4. super与 this 区别:
        1. 代表的对象不同:
          1. this:本身调用者这个对象
          2. super:代表父类对象的应用
        2. 前提:
          1. this:没有继承也可以使用
          2. super:只能在继承套件下才可以使用
        3. 构造方法
          1. this():本类的构造
          2. super():父类的构造
    4. 方法重写

      1. 前提:需要有继承关系,子类重写父类的方法
        1. 方法名必须相同
        2. 参数列表必须必须相同
        3. 修饰符:范围可以扩大 public > protected > default > private
        4. 抛出的异常:范围可以被缩写,但不能扩大 ClassNotFoundException --> Exception(大)
      2. 重写,子类的方法和父类必须要一致,方法体不同
      3. 为什么需要重写
        1. 父类的功能,子类不一定需要,不一定满足
        2. alt + insert : override
      4. 静态方法是类的方法
      5. 非静态方法是对象的方法
  3. 多态

    1. 定义:同一个方法可以根据发送对象的不同而采用多种不同的行为方式
    2. 多态存在的现象
      1. 有继承关系
      2. 子类重写父类方法
      3. 父类引用指向子类对象 Father f1 = new Son();
    3. 多态是方法的多态,属性没有多态
    4. 不能重写的方法:
      1. static:方法,属于类,不属于实例
      2. final:常量
      3. private:私有
    5. instanceof 类型转换 (引用类型)
      1. 对象 instanceof 类 结构为Boolean类型
      2. 作用:检测是否是类的对象
      3. 类型转换异常 ClassCastException
      4. 注意
        1. 父类引用指向子类对象
        2. 把子类转换成父类,向上转型。也有可能丢失方法,子类不能继承父类的私有方法
        3. 把父类转换成子类向下转型,需要强制转换
        4. 方便方法的调用,减少重复的代码,简洁
        5. 封装、继承、多态
    6. static
      1. 作用:方便在没有创建对象的情况下进行方法/变量的调用
      2. static可以用来修饰类的成员方法、类的成员变量
      3. static 可以用来编写代码块来优化程序性能
        1. 静态代码块只执行一次
        2. 匿名代码块、构造方法在创建对象时被加载
      4. 静态导入包

4、抽象类和接口

  1. 抽象类
    1. abstract修饰可以用来修饰方法(抽象方法),也可以用来修饰类(抽象类)
    2. 抽象类中可以没有抽象方法,但抽象方法一定要声明为抽象类
    3. 抽象类:不能使用new来创建对象,它是用来让子类继承的
    4. 抽象方法:只有方法的声明,没有方法的实现,它是用来让方法实现的
    5. 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则让该子类也要声明为抽象类
  2. 接口
    1. 普通类:只有具体实现
    2. 抽象类:具体实现和规范(抽象方法)都以
    3. 接口:只有规范,自己无法写方法~专业的约束。约束和实现分类:面向接口编程
    4. 接口就是规范,定义的是一组规则。
    5. 接口的本质是契约。
    6. 声明类的关键字是class,声明接口的关键字是interface
    7. 作用:
      1. 约束
      2. 定义一些方法,让不同的人实现
      3. public abstract
      4. public static final
      5. 接口不能被实例化,接口中没有构造方法
      6. implements可以实现多个接口
      7. 必须要重写接口中的方法

5、内部类及OOP实战

  1. 内部类
    1. 成员内部类
    2. 静态内部类
    3. 局部内部类
    4. 匿名内部类
  2. 异常
    1. 什么是异常
      1. 简单分类
        1. 检查性异常
        2. 运行时异常
        3. 错误
      2. 异常体系结构
        1. Java把异常当作对象来处理,并定义一个基类 java.lang.Throwable作为异常的超类
        2. 在Java API中经历定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception
      3. 异常处理机制
        1. 抛出异常
        2. 捕获异常
        3. 异常处理五个关键字:try、catch、finally、throw、throws
        4. 生成捕获代码快捷键:ctrl + alt + t
      4. 自定义异常
        1. 使用Java内置的异常可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可
        2. 自定义异常步骤
          1. 创建自定义异常类
          2. 在方法中通过throw抛出异常对象
          3. 如果在当前抛出异常的方法中处理异常,可以使用 try-catch 语句捕获并处理;否则在方法的声明处通过throws指明要抛出给方法调用者的异常,继续执行下一步操作
          4. 在出现异常方法的调用者中捕获并处理异常
    2. 实际应用中的经验总结
      1. 处理运行时异常时,采用逻辑去合理规避同时辅助 try - catch 处理
      2. 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
      3. 对于不确定的代码,也可以加上try-catch,处理潜在的异常
      4. 尽量去处理异常,切忌质数简单地调用printStackTrace() 去打印输出
      5. 具体如何处理异常,要根据不同的业务需求和异常类型去决定
      6. 尽量添加finally语句去释放占用的资源

备注

狂神说Java
这是一位很好的Java讲师——秦疆老师,视频讲述的内容很优秀。Java基础薄弱的同学,可以通过这个视频的学习,扎实Java基础,还有很多新东西等你来发现。
这篇文章是我看这个视频的笔记,包括秦老师的讲述内容和我的一些补充。
如果文章里有错误请您指出。

created by XQ_JOKER in 2021/4/19

updated by XQ_JOKER in 2021/4/23

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值