Part1

一、安装使用IDEA

Part2

一、流程控制

1.顺序结构

2.分支结构

  • if单分支结构
  • if else双分支结构
  • if else if else多分支结构
  • switch多分支结构(适用于多值情况)
  1. switch(expression){
  2. case value :
  3. //语句
  4. break; //可选
  5. case value :
  6. //语句
  7. break; //可选
  8. //你可以有任意数量的case语句
  9. default : //可选
  10. //语句
  11. }

switch case 语句有如下规则:

  1. switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
  2. switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
  3. case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
  4. 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
  5. 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
  6. switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

    3.循环结构

  • while 循环
  • do…while 循环
  • for 循环

选择循环变量时,习惯性选择i、j、k作为循环变量。

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

4.增强for循环(foreach循环)

Java5 引入了一种主要用于数组的增强型 for 循环。foreach循环用来自动遍历数组和集合中的每个元素,而无需获得数组和集合的长度,无需根据索引来访问数组元素和集合元素。

  1. for(变量类型 变量名 : 数组或集合)
  2. {
  3. //新声明的变量自动迭代访问每个元素
  4. }

变量类型 变量名:声明新的局部变量,该变量的类型必须和数组元素或集合元素的类型匹配(可使用var直接定义)。其作用域限定在循环语句块,其值与此时数组元素或集合元素的值相等。
数组或集合:要访问的数组名或集合名,或者是返回值为数组的方法。

  1. public class Test {
  2. public static void main(String args[]){
  3. int [] numbers = {10, 20, 30, 40, 50};
  4. for(int x : numbers ){
  5. System.out.print( x );
  6. System.out.print(",");
  7. }
  8. System.out.print("\n");
  9. String [] str ={"A", "B", "C", "D"};
  10. for( String s : str ) {
  11. System.out.print( s );
  12. System.out.print(' ');
  13. }
  14. }
  15. }
  16. /*输出结果
  17. 10,20,30,40,50,
  18. A B C D
  19. */

注:临时变量只是迭代保存了数组的值,并不能改变数组的值,因此不要对foreach循环变量进行赋值。

5.break、continue关键字

  • break:结束循环,直接跳出整个循环。
  • continue:跳过当前循环,从下次循环再执行。

    Part3

    一、面向对象(上)

    1.类和对象

  • 类:相当于一个模板,是某类对象的抽象,其中定义了某类对象所具有的共同属性和方法。

    1. [修饰符] class 类名{
    2. 零个到多个构造器
    3. 零个到多个成员变量
    4. 零个到多个方法
    5. }

    修饰符可以是public、final、abstract,或者完全省略这三个修饰符。类中的成员可以相互调用,但static修饰的成员不能访问没有static修饰的成员。

  • 对象:object或instance(实例),是由类所创建的一个具体的存在。通过new关键字来调用某个类的构造器即可创建这个类的实例,创建对象后才能访问对象的实例变量和调用对象的方法。static修饰的方法和成员变量即可通过类来调用,也可通过对象调用;没有static修饰的普通方法和成员变量,只能通过实例来调用。

    1. //调用构造器:类名 变量名 = new 类的构造器();
    2. public class Dog {
    3. //只有一个参数的构造器
    4. public Dog(String name){
    5. System.out.println("小狗的名字是 : " + name );
    6. }
    7. public static void main(String[] args){
    8. Dog mydog = new Dog("小黑");//创建一个实例
    9. }
    10. }

    2.属性(成员变量)

    1. [修饰符] 类型 成员变量名 [= 默认值];
  • 修饰符:public、protected、private、static、final,其中public、protected、private最多只能有一个,可以与static、final组合起来修饰成员变量。

  • staic是一个特殊的关键字,可以用来修饰方法、成员变量等成员,static修饰的成员表明它属于类本身,不属于这个类的单个实例,通常把static修饰的成员称为类变量、类方法。不使用static修饰的成员属于这个类的实例,称为实例变量、实例方法。静态成员不能直接访问非静态成员。
  • 变量的默认初始化

image.png

3.方法详解

方法是类和对象行为特征的抽象,用于实现一定功能的代码。在面向对象中,类是程序的基本单位,方法不能独立存在,方法是从属于类和对象的。通常建议方法名以动词开头。

  • 方法的声明格式:

    1. [修饰符1 修饰符2 ……] 返回值类型 方法名(形参列表){
    2. 语句块
    3. }
  • 调用方式:

方法不能被独立执行,必须通过使用类或对象来作为调用者。

  1. 对象名.方法名(实参列表)
  2. 类名.方法名(实参列表)
  • 形参个数可变的方法

JDK1.5之后,Java允许定义形参个数可变的参数,只需在定义方法时,在形参的类型后增加…,则表明该形参可以接受多个参数值,多个参数值被当成数组传入。

  1. public class Main {
  2. //定义一个形参个数可变的方法
  3. public static void test(int a, String...books){
  4. for(var tmp : books){
  5. System.out.println(tmp);
  6. }
  7. System.out.println(a);
  8. }
  9. public static void main(String[] args){
  10. test(5, "A", "B", "C");
  11. }
  12. }
  1. A
  2. B
  3. C
  4. 5

形参个数可变的参数本质上就是一个数组参数,下面两个定义的效果完全一样。两个定义方法都把books当作数组处理,也就是说使用可变形参个数定义的方法,调用时也可传入一个数组。

  1. //可变参数个数的定义方法
  2. public static void test(int a, String...books)
  3. //数组形参定义方法
  4. public static void test(int a, String[] books)

但对于可变形参个数的方法,调用时更加简洁。需要注意的是,数组形式的形参可以在形参列表的任意位置,而可变个数的形参只能处于形参列表的最后,一个方法中最多只能有一个可变个数的形参。

  1. test(5, "A", "B", "C");
  2. test(5, new String[] {"A", "B", "C"});//传入数组时的调用方式
  • 方法的递归调用

一个方法体中直接或间接的调用它自身,称为方法的递归调用。本质是一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
如求斐波那契数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n)

  1. public class Main {
  2. public static int fn(int n){
  3. if(n == 0){
  4. return 1;
  5. }
  6. else if(n == 1){
  7. return 4;
  8. }
  9. else{
  10. //递归调用,向小的一端递归
  11. return 2 * fn(n - 1) + fn(n - 2);
  12. }
  13. }
  14. public static void main(String[] args){
  15. System.out.println(fn(10));
  16. }
  17. }

注:当一个方法不断地调用自身时,必须在某个时刻的返回值是确定的,即不再调用自身,否则这种递归就变成了无穷递归。因此定义递归方法时,有一条最重要的规则:递归一定要向已知方向递归。
如:f(20)=1,f(21)=4,f(n+2)=2*f(n+1)+f(n),求f(10)

  1. public static int fn(int n){
  2. if(n == 20){
  3. return 1;
  4. }
  5. else if(n == 21){
  6. return 4;
  7. }
  8. else{
  9. //递归调用,向大的一端递归,因为大的一端是已知的
  10. return fn(n + 2) - 2 * fn(n + 1);
  11. }
  12. }

任何能用递归解决的问题都能用迭代解决,递归更简洁,但耗时耗内存,在不考虑效率时可以使用。

  • 方法重载(Overload)

方法的重载是指一个类中可以定义多个方法名相同,但形参不同的方法(类型不同、个数不同、顺序不同等,能通过形参区分就行)。调用时,会根据不同的参数自动匹配对应的方法。重载的方法,实际上是完全不同的方法,只是名称相同而已。含义相同的方法可以根据形参不同从而调用不同的形式,提供多种选择。

  1. public class Main {
  2. public static int add(int a, int b){
  3. return a + b;
  4. };
  5. public static int add(int a, int b, int c){
  6. return a + b + c;
  7. }
  8. public static void main(String[] args){
  9. System.out.println(add(1, 2, 3));
  10. }
  11. }

4.构造器

构造器是一个类创建对象的根本途径,构造器是一个特殊的方法,因此定义构造器的语法格式和定义方法的格式很像。

  1. [修饰符] 构造器名 (形参列表){
  2. //零到多条可执行语句组成的构造器执行体
  3. }
  • 修饰符:public、protected、private之一或者省略。
  • 构造器名:必须与类名相同。
  • 形参列表:和定义方法时一样。
  • 和方法的不同之处:不能定义返回值类型,如果定义了返回值类型则变成了方法。构造器的返回值是隐式的,返回的是当前类的实例。
  • 如果没有为类编写构造器,系统会提供一个默认的构造器,系统提供的构造器是没有参数的。一旦为类编写了构造器,则系统不再为类提供构造器。

    5.数组

    数组要求所有数组元素具有相同的数据类型,因此,数组元素的类型是唯一的,一个数组只能存储一种类型的数据。(注:有时会造成一个数组可以存放多种数据类型的假象,数组可以存储引用类型,如一个类的多个实例,类和类之间有继承关系,但数组里存储的内容依旧是同一个类的实例)

  • 一旦数组初始化完成,数组在内存中所占的空间就被确定,数组的长度就不可改变,即使把数组的数据都清空,所占空间依然保留。

  • 数组本身也是一种数据类型,是引用类型,如int[]就是一种引用类型,创建int[]类型的对象就是存储int类型数据的数组。
  • 定义数组:

    1. type[] arrayName;
    2. type arrayName[];

    通常推荐使用第一种定义方法,这种方式很容易理解,type[]是一种类型,而arrayName则是变量名。
    注:数组是一种引用类型,使用它定义一个变量时,仅仅表示定义了一个引用变量(也就是一个指针),这个指针还未指向任何有效的内存,因此定义数组时不能指定数组长度,数组也只有在初始化后才能使用。

  • 数组的初始化

初始化:为数组元素分配内存空间,并为每个元素赋初始值。有两种方式:静态初始化(显式指定每个数组元素的初始值,由系统决定数组长度)和动态初始化(初始化时只指定数组长度,由系统为数组元素分配初始值)。

  1. //静态初始化
  2. arrayName = new type[] {element1, element2, element3 ...}
  3. type[] arrayName = {element1, element2, element3 ...}//定义数组的同时初始化,推荐使用
  4. Object[] objArr;
  5. objArr = new String[] {"A", "B", "C"};
  6. //String类是Object类的子类,子类实例是一种特殊的父类实例。

type就是数组元素的类型,此处的type必须与定义数组变量时所使用的type相同,或者是定义数组变量时type的子类。显示指定的数组元素与new后的type类型相同或者是其子类的实例。

  1. //动态初始化
  2. arrayName = new type[length];
  3. type[] arrayName = new type[length];//定义数组的同时初始化

与静态初始化相同,此处的type必须与定义数组变量时所使用的type相同,或者是定义数组变量时type的子类。
注:不要同时使用静态初始化和动态初始化,即指定数组的长度也为每个元素分配初始值。

  • 使用数组

访问数组元素通过数组索引,数组索引从0开始,最后一个元素的索引值为数组长度减1。