2. Java基本语法

一、关键字和保留字

1. 关键字

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

常用关键字:

image-20210715100617437

image-20210715100639606

2. 保留字

现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字。

二、标识符

Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符。

标识符的命名规则

  • 由26个英文字母大小写,0-9,_或 $ 组成
  • 数字不可以开头。
  • 不可以使用关键字和保留字,但能包含关键字和保留字。
  • Java中严格区分大小写,长度无限制。
  • 标识符不能包含空格。

Java中的命名规范

  • 包名:多单词组成时所有字母都小写:xxxyyyzzz
  • 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
  • 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单 词开始每个
    单词首字母大写:xxxYyyZzz
  • 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ

三、变量

1. 变量的概念

  • 内存中的一个存储区域
  • 该区域的数据可以在同一类型范围内不断变化
  • 变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值

2. 变量的声明与使用

  • 变量的声明:<数据类型> <变量名>
  • 变量的赋值:<变量名> = <值>
  • 变量的声明与赋值:<数据类型> <变量名> = <值>
  • 变量的使用:使用变量名来访问这块区域的数据

Notes:

  • Java中每个变量必须先声明,后使用;
  • 定义在方法中的变量没有默认值;
  • 变量的作用域:其定义所在的一对{ }内 ,变量只有在其作用域内才有效;
  • 同一个作用域内,不能定义重名的变量,否则会报错;

3. Java中的数据类型

  1. 按照数据类型来分:

    image-20210715171610962

    • 整型变量:

      image-20210715172235986

      Notes:

      1. 当赋值超过数据类型的最大值时,编译报错;
      2. 定义long型变量时,必须以“L”或“l”结尾;
      3. Java中整型常量默认的数据类型为“int”类型,若要声明“long”型的常量,需要在结尾加“L”或“l”;
      4. 定义整型变量时通常定义为“int”类型;
    • 浮点型变量:

      浮点数字的表示方法:

      • 十进制表示法:0.520,3.14,521.1314……
      • 科学计数法:5.2e-1,3.14e,5.121314e2 (ea代表10^a)……

      image-20210715173256256

      Notes:

      1. float可精确到小数点后7位,double可精确到小数点后14位;
      2. Java中的浮点常量的默认数据类型为double型,若声明float型常量,需要在结尾加“f”或“F”;
      3. 声明float型变量时需要在结尾加“f”或“F”;
      4. float只占用4个字节,但是比long型的表示范围大;
      5. 定义浮点型变量时通常定义为double型变量;
    • 字符型变量:

      一个字符占用2个字节

      字符型变量的表示方法:

      • 使用单引号括起来的单个字符char c = 'a';
      • 使用转义字符==\==来将其后的字符转变为特殊字符型常量:char c = '\n';
      • 直接使用 Unicode 值来表示字符型常量:char c = '\u0043';

      Notes:

      1. Java使用Unicode字符集

        ,可表示不同语言中的单个字符(一个字母、一个汉字等);

      2. 各种字符集详解

      3. 转义字符

    • 布尔类型变量:
      只能取“true”或“false”两个值之一。

    • 字符串类型

      • 变量的声明:String str = "字符串";

      • String可以和8种基本的数据类型变量做运算,且运算只能是连接运算,运算结果为String类型

        int num = 1001;
        String numStr = "学号:";
        String infoStr = numStr + num;
        
  2. 类型转换
    前提:布尔型不能参加数据类型转换

    • 自动类型提升

      • 基本数据类型:

        当容量小的数据类型的与容量大的做运算时,结果自动提升为容量大的数据类型。image-20210715191335056

        Note:当char、byte、short变量做运算时,结果为int类型。

      • 引用数据类型:

        • 基本数据类型与String类型做连接运算,都提升为String类型;
    • 强制类型转换
      自动类型提升的逆运算。

      语法:<低级变量> = <数据类型> <高级变量>

      Note:

      基本数据类型中的强制类型转换执行的是截断操作,可能会丢失精度;

      引用数据类型中的强制类型转换……

    • 几种编码情况:

      • long l = 123233;这种情况实际上是先将int型的常量提升为long型,再赋值给变量
        如果将赋值的范围调整到int到long之间时,会报错:
        image-20210715202844729

        说明一开始的值是“int”类型的常量,赋值时将类型提升为long类型。

      • 默认常量类型:

        byte b1 = 1;
        byte b2 = b1 + 1;
        

        编译报错:

        image-20210716163747045

        在Java中,整型常量默认类型为int型;浮点型常量默认类型为double型。

  3. 按照声明的位置不同来分:

    image-20210715172044746

四、运算符

  1. 算术运算符
    image-20210717113123490

    • 对于除号,若两边都是整数。则结果保留整数,否则自动提升为等级较高的类型;
    • 取模运算结果的正负号与第一个数的符号相同;
    • 自增、自减不会改变原有变量的数据类型;
  2. 赋值运算符:=

    +=*=\=-=%=

    以上五种运算符不改变变量的数据类型。

  3. 比较运算符
    image-20210718110649938

    Note:

    • 比较运算符的结果为Boolean类型;
  4. 逻辑运算符
    image-20210718111816826

    短路特性:

    boolean b1 = true;
    int num1 = 10;
    if (b1 & num1++ > 0){
        System.out.println("1");
    }else{
        System.out.println("2");
    }
    System.out.println("num1 = " + num1);
    
    boolean b2 = true;
    int num2 = 10;
    if (b2  & num2++ > 0){
        System.out.println("1");
    }else{
        System.out.println("2");
    }
    System.out.println("num2 = " + num2);
    

    输出结果为:

    image-20210718115030636

    现在将b1和b2改为false:

    boolean b1 = true;
    b1 = false;
    int num1 = 10;
    if (b1 & num1++ > 0){
        System.out.println("1");
    }else{
        System.out.println("2");
    }
    System.out.println("num1 = " + num1);
    
    boolean b2 = true;
    b2 = false;
    int num2 = 10;
    if (b2 && num2++ > 0){
        System.out.println("1");
    }else{
        System.out.println("2");
    }
    System.out.println("num2 = " + num2);
    

    则输出结果为:

    image-20210718115304840

    当使用短路与和短路或运算符时,满足短路条件后,后面的条件语句不会执行

  5. 位运算符

    image-20210718162636902

    image-20210718165524872

  6. 三元运算符
    (条件表达式) ? 表达式1 ? 表达式2
    当表达式的值为true时,执行表达式1;否则执行表达式2。

    表达式1的类型和表达式2的类型最终会统一到同一个类型中。

  7. 运算符的优先级
    image-20210718165558319

五、流程控制

1. 顺序结构

程序从上到下逐行地执行,中间没有任何判断和跳转。

  • Java中的三种输出方式

    • System.out.print
    • System.out.printf
    • System.out.println
  • 使用Scanner进行数据的输入

    //1. 导包
    import java.util.Scanner;
    
    //2. Scanner的实例化
    Scanner scanner = new Scanner(System.in);
    
    //3. 使用Scanner对象调用对应的方法来获取指定类型的变量值
    int num = scanner.nextInt();
    
    • 常用方法

      • 输入类

        返回值类型方法名描述
        booleannextBoolean()Scans the next token of the input into a boolean value and returns that value.
        bytenextByte()Scans the next token of the input as a byte.
        doublenextDouble()Scans the next token of the input as a double.
        floatnextFloat()Scans the next token of the input as a float.
        intnextInt()Scans the next token of the input as an int.
        Stringnext()Finds and returns the next complete token from this scanner.
        StringnextLine()Advances this scanner past the current line and returns the input that was skipped.
        longnextLong()Scans the next token of the input as a long.
        shortnextShort()Scans the next token of the input as a short.
      • 判断类

        返回值类型方法名描述
        booleanhasNext()Returns true if this scanner has another token in its input.
        booleanhasNextBigDecimal()Returns true if the next token in this scanner’s input can be interpreted as a BigDecimal using the nextBigDecimal() method.
        booleanhasNextBigInteger()Returns true if the next token in this scanner’s input can be interpreted as a BigInteger in the default radix using the nextBigInteger() method.
        booleanhasNextBoolean()Returns true if the next token in this scanner’s input can be interpreted as a boolean value using a case insensitive pattern created from the string “true|false”.
        booleanhasNextByte()Returns true if the next token in this scanner’s input can be interpreted as a byte value in the default radix using the nextByte() method.
        booleanhasNextDouble()Returns true if the next token in this scanner’s input can be interpreted as a double value using the nextDouble() method.
        booleanhasNextFloat()Returns true if the next token in this scanner’s input can be interpreted as a float value using the nextFloat() method.
        booleanhasNextInt()Returns true if the next token in this scanner’s input can be interpreted as an int value in the default radix using the nextInt() method.
        booleanhasNextLine()Returns true if there is another line in the input of this scanner.
        booleanhasNextLong()Returns true if the next token in this scanner’s input can be interpreted as a long value in the default radix using the nextLong() method.
        booleanhasNextShort()Returns true if the next token in this scanner’s input can be interpreted as a short value in the default radix using the nextShort() method.
  • 产生随机数的两种方法:

    • Random类

      public static void main(String[] args){
          Random r = new Random(seed);
          int num = r.nextInt(range);
      }
      
    • Math类

      public static void main(String[] args){
          int max = 100,min = 1;
          int num = (int) (Math.random()*(max - min +1) + min); //[1, 100)
          System.out.println(ran2);
      }
      

2. 分支结构

1)if-else结构

  • if (条件表达式){
    	执行代码块;	
    }
    

    执行逻辑:

    image-20210720165440246

  • if (条件表达式){
        执行语句块1} else {
        执行语句块2}
    

    执行逻辑:

    image-20210720165643894

  • if (条件表达式1){
        执行代码块1} else if (条件表达式2){
        执行代码块2}…… else if (条件表达式n){
        执行代码块n;
    } else {
        执行代码块0}
    

    执行逻辑:

    image-20210720170042279

  • 例题

    • 岳小鹏参加Java考试,他和父亲岳不群达成承诺:
      如果:
      成绩为100分时,奖励一辆BMW;
      成绩为(80,99]时,奖励一台iphone xs max;
      当成绩为[60,80]时,奖励一个 iPad;
      其它时,什么奖励也没有。
      请从键盘输入岳小鹏的期末成绩,并加以判断

      poublic static void main(String[] args){
          Scanner scanner = new Scanner(System.in);
          int score = scanner.nextInt();
          
          if (score == 100){
              System.out.println("奖励一辆BMW");
          } else if (score > 80){
              System.out.println("奖励一台iphone xs max");
          } else if (score >= 60){
              System.out.println("奖励一个 iPad");
          } else {
              System.out.println("什么奖励也没有");
          }
      }
      
      /*
       * Notes:
       * 1. 当判断条件之间为包含关系时,需要注意条件判断的位置,一般范围大的条件后判断;
       * 2. 当判断条件之间为互斥关系时,条件判断的先后顺序无所谓。
       */
      
    • 由键盘输入三个整数分别存入变量num1、num2、num3,对它们进行排序(使用 if-else if-else),并且从小到大输出。

      public static void main(String[] args){
          Scanner scan = new Scanner(System.in);
          System.out.println("请输入第一个整数:");
          int num1 = scan.nextInt();
          System.out.println("请输入第二个整数:");
          int num2 = scan.nextInt();
          System.out.println("请输入第三个整数:");
          int num3 = scan.nextInt();
          
          if (num1 > num2){
              if (num1 > num3){
                  if (num2 > num3){
                      System.out.println(num1 + "," + num2 + "," + num3);
                  } else {
                      System.out.println(num1 + "," + num3 + "," + num2);
                  }
              } else {
                  System.out.println(num3 + "," + num1 + "," + num2);
              }
          } else {		//num2 > num1
              if (num3 > num1){
                  if (num3 > num2){
                      System.out.println(num3 + "," + num2 + "," + num1);
                  } else {
                      System.out.println(num2 + "," + num3 + "," + num1);
                  }
              } else {
                  System.out.println(num2 + "," + num1 + "," + num3);
              }
          }
      }
      

2)switch-case结构

switch(表达式){
    case 常量1:
        语句1;
        <break;>
    case 常量2:
        语句2;
        <break;> 
    … …
    case 常量N:
        语句N;
        <break;>
    default:
        语句;
        <break;>
}
  • 根据switch括号中表达式的值依次匹配各个case中的常量,一旦匹配成功,执行相应case中的语句。
  • break的作用:跳出当前的switch-case结构。
  • break语句可有可无,可根据实际情况决定。
    若没有break语句,则执行完当前case中的语句后会继续向下执行,直到遇到break语句或执行结束。

Notes:

  • switch(表达式)中表达式的值必须是下述几种类型之一:byteshortcharint枚举 (jdk 5.0),String (jdk 7.0);
  • case子句中的值必须是常量,不能是变量名或不确定的表达式值;
  • 同一个switch语句,所有case子句中的常量值互不相同;
  • default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时,执行default
  • 练习:

    • 使用 switch 把小写类型的 char型转为大写。只转换 a, b, c, d, e. 其它的输出 “other”。

      public static void main(String[] args) {
          Scanner scan = new Scanner(System.in);
          System.out.println("请输入一个小写字母:");
          String str = scan.next();
      
          switch(str) {
              case "a":
                  System.out.println("A");
                  break;
              case "b":
                  System.out.println("B");
                  break;
              case "c":
                  System.out.println("C");
              default:
                  System.out.println("other");
          }
      }
      
    • 根据用于指定月份,打印该月份所属的季节。(3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季)

      public static void main(String[] args) {
          Scanner scan = new Scanner(System.in);
          System.out.println("请输入月份:");
          int monthNum = scan.nextInt();
      
          switch(monthNum) {
              case 3:
              case 4:
              case 5:
                  System.out.println("春季");
                  break;
              case 6:
              case 7:
              case 8:
                  System.out.println("夏季");
                  break;
              case 9:
              case 10:
              case 11:
                  System.out.println("秋季");
                  break;
              case 12:
              case 1:
              case 2:
                  System.out.println("冬季");
                  break;
          }
      }
      
    • 从键盘上输入年、月、日,要求通过程序输出输入的该日期为当前年份的第几天。

      public static void main(String[] args) {
          Scanner scan = new Scanner(System.in);
          System.out.println("请输入年份:");
          int year = scan.nextInt();
          System.out.println("请输入月份:");
          int mounth = scan.nextInt();
          System.out.println("请输入日期:");
          int day = scan.nextInt();
      
          //二月份默认为28天
          int febDays = 28;
          int sumDays = 0;
          
          //判断闰年
          if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
              febDays = 29;
          }
      
          switch(mounth) {
              case 12:
                  sumDays += 31;
              case 11:
                  sumDays += 30;
              case 10:
                  sumDays += 31;
              case 9:
                  sumDays += 30;
              case 8:
                  sumDays += 31;
              case 7: 
                  sumDays += 31;
              case 6:
                  sumDays += 30;
              case 5:
                  sumDays += 31;
              case 4:
                  sumDays += 30;
              case 3:
                  sumDays += 31;
              case 2:
                  sumDays += febDays;
              case 1: 
                  sumDays += day;
                  System.out.println("总天数为:" + sumDays);
          }
      }
      
      /* 
       *利用无break的穿透功能,倒着匹配,实现累加
       */
      

3) if-else和switch-case的联系与区别

  1. 如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高。
  2. 对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。
  3. 使用switch-case的,都可以改写为if-else。反之不成立。

3. 循环结构

循环四要素

  1. 初始化部分(init_statement)
  2. 循环条件部分(test_exp)
  3. 循环体部分(body_statement)
  4. 迭代部分(alter_statement)

1) for循环

for (初始化部分; 循环条件部分; 迭代部分){
    循环体部分;
}
  • break和continue

    • break
      跳出当前循环,执行循环后的代码
    • continue
      跳过执行当前的一次循环体,继续执行下一次循环的循环体
    • 带标签的break和continue
      跳出或跳过指定标签的循环。
  • 练习

    • 编写程序从1循环到150,并在每行打印一个值,另外在每个3的倍数行上打印出“foo”,在每个5的倍数行上打印“biz”,在每个7的倍数行上打印输出“baz”。

      for (int i = 1; i <= 150; i++){
          System.out.print(i);
          if (i % 3 == 0){
              System.out.print("\tfoo");
          }
          if (i % 5 == 0){
              System.out.print("\tbiz");
          }
          if (i % 7 == 0){
              System.out.print("\tbaz");
          }
          System.out.println();
      }
      
    • 求最大公约数(Greatest Common Divisor)和最小公倍数(Greatest Common Multiple)

      /* 
       * 1. 辗转相除法:
       * 公式:gcd(m, n) = gcd(n, m mod n)
       */
      public static int getGcd(int m, int n){
          //余数
          int r = 0;
          do{
              r = m % n;
              m = n;
              n = r;
          }while (r != 0)
      }
      
      /*
       * 2. 辗转相减法:
       * 第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
       * 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得 
       * 的减数和差相等为止。
       */
      public static int getGcd(int m, int n){
          while (m != n){
              if (m > n){
                  m -= n;
              } else {
                  n -= m;
              }
          }
          return m;
      }
      
      /*
       * 最小公倍数:
       * 公式:gcm(m, n) * gcd(m, n) = m * n
       */
      public static int getGcm(int m, int n){
          return m * n / getGcd(m, n);
      }
      

2) while循环

初始化部分;
while (条件判断部分){
    迭代部分;
    循环体部分;
}

3) do-while循环

初始化部分;
while (条件判断部分) {
    迭代部分;
    循环体部分;
}

do-while循环至少执行一次循环体。

六、数组

1. 基本概念

数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

  • 数组名:数组的唯一标识
  • 元素:数组中的每一个数据
  • 下标、索引:数组元素的位置(从0开始)
  • 数组长度:数组中元素的个数

Notes:

  • 数组本身是引用数据类型,而数组中的元素可以是任意数据类型,包括基本数据类型和引用数据类型;
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址;
  • 数组的长度一旦确定,就不能修改
  • 通过索引访问数组元素速度非常快
  • 索引:
    • 正序索引:从0开始到数组长度-1
    • 倒序索引:从-1开始到数组长度-1的相反数

2. 一维数组及其使用

  • 数组的声明方式

    • type arrayName[];
    • type[] arrayName;
  • 数组的初始化方式

    • 静态初始化:arrayName = new type[]{value0, value1, ……, valuen};
    • 动态初始化:type[] arrayName = new type[number];
      type arrayName[] = new type[number];

    Notes:

    • 数组本身为引用数据类型,因此需要使用new关键字来分配空间;

    • 静态初始化中若元素类型是基本数据类型的话,可以写成type arrayName = {value0, value1, ……, valuen},该方式为Java中的类型推断

    • 动态初始化中的number为数组元素的总个数(即数组的长度),不是索引值的大小;

      索引值与数组长度的关系:

      数组长度为n,则索引值为【0, n - 1】;

    • 动态初始化中的number可以是变量,也可以是常量

    • 动态初始化的方式与变量声明+赋值的方式类似,动态初始化后系统会自动赋默认值;

    • 默认初始化值:在动态初始化时,指定数组大小后,JVM虚拟机会自动对相应的内存空间赋值。

      • 对于基本数据类型来说,默认初始化的值有所不同:
        image-20210722172039716
      • 对于引用数据类型来说,默认初始化的值为null;
  • 调用指定位置的元素

    • 获取元素的值:type var = arayName[index];
    • 给指定的元素赋值:arrayName[index] = value;
  • 获取数组的长度

    • 使用数组的length属性:arrayName.length
  • 数组的遍历

    • 普通循环:

      for (int i = 0; i < arrayName.length; i++){
          System.out.println(arrayName[i]);
      }
      
    • 增强型循环:

      for(type element: arrayName){
          System.out.println(element);
      }
      
  • 数组内存空间解析

    • 内存结构简化图解:
      image-20210722174504093

    • 分析:

      public static void main(String[] args){
      	int[] arr = new int[]{1,2,3};
          String[] arr1 = new String[4];
          arr1[1] = “刘德华”;
          arr1[2] = “张学友”;
          arr1 = new String[3];
      }
      

      image-20210722181547681

    • Note:

      1. System.out.println(char[])当输出char类型的数组名时,输出的是数组中的元素;
      2. System.out.println(char[])当输出int类型的数组名时,输出的是数组所在内存的地址;
      char[] c = new char[]{'a', 'b', 'c'};
      System.out.println(c);
      //输出:abc
      
      int[] i = new int[]{1, 2, 3};
      System.out.println(i);
      /* 
       *输出:
       * [I@3830f1c0
       * ||^表示为该数组所在的地址
       * |^表示为该数组为int型数组
       * ^表示为该数组为一维数组   
       */
      
  • 练习

    • 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
      成绩>=最高分-10 等级为’A’
      成绩>=最高分-20 等级为’B’
      成绩>=最高分-30 等级为’C’
      其余 等级为’D’

      public static void main(String[] args) {
      		Scanner scan = new Scanner(System.in);
      		
      		System.out.println("请输入学生数量:");
      		int studentNum = scan.nextInt();
      		
      		int scores[] = new int[studentNum];
      		int maxScore = 0;
      		System.out.println("请依次输入学生的成绩:");
      		for (int i = 0; i < studentNum; i++) {
      			scores[i] = scan.nextInt();
      			if (scores[i] > maxScore) {
      				maxScore = scores[i];
      			}
      		}
      		
      		/*
      		int maxScore = 0;
      		for (int i  = 0; i < scores.length - 1; i++) {
      			if (maxScore < scores[i]) {
      				maxScore = scores[i];
      			}
      		}
      		*/
      		
      		for (int i = 0; i < scores.length; i++) {
      			if (scores[i] >= maxScore - 10) {
      				System.out.println("A");
      			} else if (scores[i] >= maxScore - 20) {
      				System.out.println("B");
      			} else if (scores[i] >= maxScore - 30) {
      				System.out.println("C");
      			} else {
      				System.out.println("D");
      			}
      		}
      	}
      

3. 二维数组及其使用

对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。

  • 二维数组的声明

    • type arrayName[][];
    • type[][] arrayName;
    • type[] arrayName[];
  • 二维数组的初始化

    • 静态初始化:type[][] arrayName = new type[][]{{value11, value12, ……},{value, ……}, ……};
    • 动态初始化:type [][] = arrayName = new type[rows][lines]

    动态初始化中rows必须指定,lines可指定,可不指定。

    默认初始化值

    针对于初始化方式一:比如:int[][] arr = new int[4][3];

    •  外层元素的初始化值为:地址值
      
    •  内层元素的初始化值为:与一维数组初始化情况相同
      

    针对于初始化方式二:比如:int[][] arr = new int[4][];

    •  外层元素的初始化值为:null
      
    •  内层元素的初始化值为:不能调用,否则报错。
      
  • 调用指定位置的元素

    • arrayName[num1][num2];
  • 获取二维数组的长度

    • arratName.length;:二维数组中一维数组的个数
    • arrayNamej[0].length:二维数组中一维数组中的元素个数
  • 二维数组的遍历

    for (int i = 0; i < arrayName.length; i++){
        for (int j = 0; j < arrayName[i].length; j++){
            arrayName[i][j];
        }
    }
    
  • 二维数组的内存空间解析

image-20210724105357118

  • 练习

    打印一个10行的杨辉三角

    image-20210724155519823
    public static void main(String[] args) {
    		int[][] yangHuiTrangle = new int[10][];
    		
    		yangHuiTrangle[0] = new int[] {1};
    		yangHuiTrangle[1] = new int[] {1, 1};
    		
    		for (int i = 2; i < 10; i++) {
    			yangHuiTrangle[i] = new int[i + 1];
    			for (int j = 1; j <= yangHuiTrangle[i].length - 1; j ++) {
    				yangHuiTrangle[i][j] = yangHuiTrangle[i - 1][j] + yangHuiTrangle[i - 1][j - 1];
    			}
    			yangHuiTrangle[i][0] = 1;
    			yangHuiTrangle[i][i] = 1;
    		}
    		
    		for (int i = 0; i < yangHuiTrangle.length; i++) {
    			for (int j = 0; j < yangHuiTrangle[i].length; j++) {
    				System.out.printf("%d\t", yangHuiTrangle[i][j]);
    			}
    			System.out.println();
    		}
    	}
    

4. 有关算法

1) 数组元素的赋值

练习1:创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。

public static void main(String[] args) {
    int[] array = new int[6];

    for (int i = 0; i < 6; i++) {
        array[i] = (int)(Math.random() * 30) + 1;
        for (int j = 0; j < i; j++) {
            if (array[i] == array[j]) {
                i--;
                break;				
            }
        }
    }

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

从键盘输入一个整数(1~20)

则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。例如: 输入数字2,则程序输出:

1 2

4 3

输入数字3,则程序输出:

1 2 3

8 9 4

7 6 5

输入数字4, 则程序输出:

1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入一个数:");
		int length = scanner.nextInt();
		
		int [][] array = new int[length][length];
		
		// k = 1表示向右;k = 2表示向下;K = 3表示向左;k = 4表示向上
		int k = 1;
		int x = 0;
		int y = 0;
		for (int i = 1; i <= length * length; i++) {
			if (k == 1) {
				if (y < length && array[x][y] == 0) {
					array[x][y] = i;
					y++;
				} else {
					k = 2;
					x++;
					y--;
					i--;
				}
			} else if (k ==2) {
				if (x < length && array[x][y] == 0) {
					array[x][y] = i;
					x++;
				} else {
					k = 3;
					x--;
					y--;
					i--;
				}
			} else if (k ==3) {
				if (y >= 0 && array[x][y] == 0) {
					array[x][y] = i;
					y--;
				} else {
					k = 4;
					x--;
					y++;
					i--;
				}
			} else if (k ==4) {
				if (x >= 0 && array[x][y] == 0) {
					array[x][y] = i;
					x--;
				} else {
					k = 1;
					x++;
					y++;
					i--;
				}
			}
		}
		
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j] + " ");
			}
			System.out.println();
		}
	}

2) 数组的复制

使用简单数组
(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。
思考:array1和array2是什么关系?
拓展:修改题目,实现array2对array1数组的复制

public static void main(String[] args) {
    int[] array1, array2;

    array1 = new int[]{2, 3, 5, 7, 11, 13, 17, 19};

    for (int i = 0; i < array1.length; i++){
        System.out.print(array1[i] + "\t");
    }
    System.out.println();

    //array2 = array1;不能实现复制
    //数组的复制
    array2 = new int[array1.length];
    for (int i = 0; i < array2.length; i++){
        array2[i] = array1[i];
    }
    
    for (int i = 0; i < array2.length; i += 2){
        array2[i] = i;
    }

    for (int i = 0; i < array1.length; i++){
        System.out.print(array1[i] + "\t");
    }
}

3) 排序算法

冒泡排序
/*
由小到大排序
*/
public static int[] bubbleSort(int[] array){
    for (int i = 0; i < array.length; i++){
        boolean flag = true;		//标志位,若一轮下来没有元素被交换,则表示该序列已有序
        for (int j = 0; j < array.length - i - 1; j++){
            if (array[j] > array[j + 1]){
                int temp = array[j + 1];
                array[j + 1] = array[j];
                array[j] = temp;
                flag = false;
            }
        }
        if (flage){
            break;
        }
    }
}
快速排序
private static void swap(int[] data, int i, int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

private static void subSort(int[] data, int start, int end) {
    if (start < end) {
        int base = data[start];
        int low = start;
        int high = end + 1;
        while (true) {
            while (low < end && data[++low] - base <= 0)
                ;
            while (high > start && data[--high] - base >= 0)
                ;
            if (low < high) {
                swap(data, low, high);
            } else {
                break;
            }
        }
        swap(data, start, high);

        subSort(data, start, high - 1);
        subSort(data, high + 1, end);
    }
}
public static void quickSort(int[] data){
    subSort(data,0,data.length-1);
}

4)查找算法

线性查找

按着数组的顺序往下找

public static int search(int[] array, int dest){
    for (int i = 0; i < array.length; i++){
        if (array[i] == dest){
            return i;
        }
    }
    return -1;
}
二分法查找

适用于有序数组

public static int binarySearch(int[] array, int dest){
    int front = 0;
    int behind = array.length - 1;
    int mid;
    while (front <= behind){
        mid = (front + behind) / 2;
        if (dest > array[mid]){
            front = mid + 1;
        } else  if (dest < array[mid]){
            behind = mid - 1;
        } else if (dest == array[mid]) {
            return mid;
        }
    }
    return -1;
}

7. Arrays工具类

  • 常用方法
    image-20210725174153894
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值