关键字与保留字

关键字(keyword)

  1. 定义:被Java语言赋予特殊含义,用作专门用途的字符(单词)。
  2. 特点:关键字中所有字母都为小写。
  3. 官方地址:https://docs.oracle.com/javase/tutorial/java/nutsandbolts.html

保留字(reserved word)

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

    • 例:goto、const……

标识符(Identifier)

标识符

  1. Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
  2. 比如:类名、变量名、方法名、接口名、包名……
  3. 技巧:凡是自己可以取名字的地方都叫标识符。

定义合法标识符规则(必须遵守

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

Java中名称命名规范(建议遵守

  1. 包名:多单词组成时所有字母都小写:xxxyyyzzz;

  2. 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz ;

  3. 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz;

  4. 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ;

  5. 注意

    • 注意1:在取名字时,为提高阅读性,要尽量有意义(见名知意)

    • 注意2:Java采用unicode字符集,因此标识符也可以使用汉字声明,但不建议使用

变量

变量的概念

  1. 内存中的一个存储区域;

  2. 该区域的数据可在同一类型范围内不断变化;

  3. 变量是程序中最基本的存储单元。包含变量类型(强类型:必须先声明)、变量名和存储的值。

    • 定义变量的格式:数据类型 变量名 = 变量值
      • 例:int myAge = 18;

变量的作用

  1. 用于在内存中保存数据。

变量的使用

  1. Java中每个变量必须先声明,后使用;
  2. 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了。“一对{}”即为一个作用域;
  3. 同一个作用域内,不能声明两个同名的变量。
  4. Java定义的数据类型(按数据类型分):对于每一种数据都定义了明确的具体数据类型(强类型语言),在内存中分配了不同大小的内存空间。
  • 基本数据类型(primitive type)

    (1)数值型

    • 整数类型

      • byte
        • 占用存储空间:1字节 = 8bit位
        • 表数范围:-128~127(27),最高位为符号位(0正1负),故为7次方
      • short

        • 占用存储空间:2字节
        • 表数范围:-215~215-1
      • int

        • 占用存储空间:4字节
        • 表数范围:-231~231-1(约21亿)
      • long

        • 占用存储空间:8字节
        • 表数范围:-263~263-1
      • 注意

        • Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性
        • Java的整型常量默认为int型,声明long型常量须后加‘l’或‘L’
        • Java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long
    • 浮点类型

      • 单精度float

        • 占用存储空间:4字节
        • 表数范围:-3.403E38~3.403E38
      • 双精度double

        • 占用存储空间:8字节
        • 表数范围:-1.798E308~1.798E308
      • 注意:与整数类型类似,Java浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响

      • 浮点型常量有两种表示形式

        • 十进制数形式:如:5.12、512.0f、.512 (必须有小数点)
        • 科学计数法形式:如:5.12e2、512E2、100E-2
      • float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求

      • double:双精度,精度是float的两倍。通常采用此类型

      • Java的浮点型常量默认为double型,声明float型常量,须后加’f’或’F’

      • float表示的数值范围比long还大,是因为它使用科学计数法来计数,但是精度不够

    (2)字符型

    • char

      • 1字符 = 2字节
      • 声明或定义char型变量,通常使用一对单引号(’’),内部只能写一个字符
      • 转义字符(例如:换行符\n、制表符\t、unicode编号等)
    • 布尔型

      • boolean
        • 只能取两个值之一:true、false
        • 常用于判断、循环结构
        • boolean类型数据只允许取值true和false,无null
        • 不可以使用0或非 0 的整数替代false和true,这点和C语言不同
        • Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替:true用1表示,false用0表示
  • 引用数据类型(reference type)

    • 类(class)
    • 接口(interface)
    • 数组([])
Java定义的数据类型按数据类型分类
数据类型 占用存储空间 表数范围
基本数据类型 数值型 整数类型 byte 1字节=8比特 -128~127,最高位为符号位(0正1负),故为27
short 2字节 -215~215
int 4字节 -231~231(约21亿)
long 8字节 -263~263
浮点类型 单精度float 4字节 -3.403E38~3.403E38
双精度double 8字节 -1.798E308~1.798E308
字符型 char 1字符=2字节 声明或定义char型变量,通常使用一对单引号(''),内部只能写一个字符
布尔型(boolean) true/false
引用数据类型 class
接口 interface
数组 []

编码方式(了解内容)

ASCII码

  1. 在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有0和1两种状态,因此8个二进制位就可以组合出256种状态,这被称为一个字节(byte)。一个字节一共可以用来表示 256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111

  2. ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0

  3. 缺点

  • 不能表示所有字符
  • 相同的编码表示的字符不一样:比如,130在法语编码中代表了é,在希伯来语编码中却代表(ג)了字母Gimel

Unicode编码

  1. 乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

  2. Unicode:一种编码方式,将世界上所有的符号都纳入其中。每一个符号都给予一个独一 无二的编码,使用Unicode没有乱码的问题。

  3. Unicode的缺点:

    • Unicode只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储;

    • 无法区别 Unicode 和ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有 二到三个字节是0,这对于存储空间来说是极大的浪费。

UTF-8

  1. UTF-8是在互联网上使用最广的一种Unicode的实现方式

  2. UTF-8是一种变长的编码方式。它可以使用**1-6个字节**表示一个符号,根据不同的符号而变化字节长度

  3. UTF-8的编码规则

    • 对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)

    • 对于多字节的UTF-8编码,如果编码包含n个字节,那么第一个字节的前n位为1,第一个字节的第n+1位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为”10”,其余6位用来对字符进行编码

  4. Tips:解除转义 例:解除换行符:\\n,直接显示“\n”

基本数据类型之间的运算规则

前提

  • 这里只讨论7种基本数据类型变量间的运算,不包含boolean类型的。

自动类型提升

  1. 容量小的类型自动转换为容量大的数据类型。
  • byte、char、short三种类型变量做运算时,结果为int类型,即这三个变量之间的运算结果至少要拿一个int型去接收。原因:可能是防止溢出,并且整形常量默认类型为int型,运算时如果直接加减数字的话编译不通过。

强制类型转换

  • 自动类型提升的逆运算:
  1. 需要使用强转符

  2. 强制类型转换可能导致精度损失

字符串类型:String

  1. String属于引用数据类型;

  2. 声明String类型变量时,使用一对双引号(””),长度不限(不超过内存空间即可);

  3. 定义String类型变量时,双引号之间可以没有内容,但是char类型不可以;

  4. String可以和8中基本数据类型变量作运算,且运算只能是连接运算(+),运算结果仍是String类型;

  5. 将String类型转为int型:int num1 = Integer.parseInt(str1),而不能用强制转换,强制转换只能在上述7种数据类型之间。

进制(了解内容)

  • 所有数字在计算机底层都以二进制形式存在

整数的四种表示方式

  1. 二进制(binary):0,1 ,满2进1,以0b或0B开头;
  2. 十进制(decimal):0-9 ,满10进1;
  3. 八进制(octal):0-7 ,满8进1,以数字0开头表示;
  4. 十六进制(hex):0-9及A-F,满16进1,以0x或0X开头表示。此处的A-F不区分大小写。如:0x21AF + 1 = 0X21B0。

二进制

  1. Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位

  2. 二进制的整数有如下三种形式:

  • 原码:直接将一个数值换成二进制数。最高位是符号位。

  • 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。

  • 负数的补码:其反码加1。

  • 计算机以二进制补码的形式存所有的整数。

    • 正数的原码、反码、补码都相同
    • 负数的补码是其反码+1

四种进制之间的转换

  • 以二进制位媒介来转换

运算符

  • 概念:运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等

算术运算符

运算符 运算 范例 结果
+ 正号 +3 3
- 负号 b=4;-b -4
+ 5+5 10
- 6-4 2
* 3*4 12
/ 5/5 1
% 取模(取余) 7%5 2
++
++
自增(前):先运算后取值
自增(后):先取值后运算
a=2;b=++a;
a=2;b=a++
a=3;b=3
a=3;b=2

自减(前):先运算后取值
自减(后):先取值后运算
a=2;b=–a;
a=2;b=a–
a=1;b=1
a=1;b=2
+ 字符串连接 “He”+”llo” “Hello”
  1. 整形数相除后默认结果为整形

    • 需要精确结果进行运算前需要先进行类型转换(自动转换或者强制类型转换)
  2. 取模(余)运算(%)

    • 结果符号与被模(除)数相同
  3. 自增(减)

    • (前)++:先自增1,后运算
    • (后)++:先运算,后自增1
    • 自减(略)
    • 注意:自增(减)不会改变变量本身数据类型

赋值运算符(=)

  1. 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理

  2. 支持连续赋值

    • int i1, j1;
    • i1 = j1 = 10;

比较(关系)运算符

运算符 运算 范例 结果
== 等于 4==3 false
!= 不等于 4!=3 true
< 小于 4<3 false
> 大于 4>3 true
<= 小于等于 4<=3 false
>= 大于等于 4>=3 true
instanceof 检查是否是类的对象 “Hello” instanceof String true
  1. 比较运算符的运算结果都是boolean型,也就是要么是true,要么false

  2. 区分“=”和“==”

逻辑运算符

参数 参数 逻辑与 短路与 逻辑或 短路或 逻辑非 逻辑异或
a b a&b a&&b a|b a||b !a a^b
true true true true true true false false
true false false false true true false true
false true false false true true true true
false false false false false false true false
  1. 区分逻辑与(&)和短路与(&&)

    • 相同点:运算结果相同;党符号左边为true时,都会执行符号右边的内容
    • 不同点:当左边为false时,&&不会执行符号右边的运算(短路)
    • 开发中优先使用短路与(&&)
  2. 区分逻辑或(|)和短路或(||)

    • 相同点:运算结果相同;当符号右边为false时,二者都会执行符号右边的内容
    • 不同点:当符号左边为true时,|| 不会执行符号右边的运算(短路)
    • 开发中优先使用短路或(||)
  3. 逻辑非(!)

  4. 逻辑异或(^)

    • 相同为true,不同为false

位运算符(用得较少)

运算符 运算 范例
<< 左移 3 << 2 = 12 –> 3 * 2 2 = 12
>> 右移 3 >> 1 = 1 –> 3 / 2 1= 1
>>> 无符号右移 3 >>> 1 = 1 –> 3 / 2 = 1
& 与运算 6 & 3 = 2
| 或运算 6 | 3 = 7
^ 异或运算 6 ^ 3 = 5
~ 取反运算 ~ 6 = -7

位运算符细节:

<< 空位补0,被移除的高位丢弃,空缺位补0。
>> 被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,最高位补1。
>>> 被移位二进制最高位无论是0或者是1,空缺位都用0补。
& 二进制位进行&运算,只有1&1时结果是1,否则是0。
| 二进制位进行|运算,只有0|0时结果时0,否则是1。
^ 相同的二进制位进行^运算,结果是0;1^1=0,0^0=0;不相同的二进制位^运算结果是1。1^0=1,0^1=1。
~ 正数取反,各二进制码按补码各位取反;负数取反,各二进制码按补码各位取反。
  1. 位运算符是直接对整数的二进制进行的运算

  2. 位运算符操作的都是整形的数据

  3. <<:在一定范围内,每向左移n位,相当于*2n

  4. >>:在一定范围内,每向右移n位,相当于/2n

    • 面试题:如何最高效的计算2*8?

      • 2 << 3 或 8 << 1
    • 注意:无<<<

  5. &、|、^运算

09AndOrXorOperation

  1. ~取反运算

    • 包括符号位在内取反
  2. 练习:交换两个变量的值

  • 方法一:定义临时变量

    int temp = num1;
    num1 = num2;
    num2 = temp;
  • 方法二

    num1 = num1 + num2;
    num2 = num1 - num2;
    num1 = num1 - num2;
    • 优点:不用定义临时变量、
    • 弊端:①相加操作可能超出存储范围; ②有局限性:只能适用于数值类型。
  • 方法三:使用位运算符

    num1 = num1 ^ num2;
    num2 = num1 ^ num2;
    num1 = num1 ^ num2;

三元运算符

  1. 格式:11TernaryOperation

    • 条件表达式的结果为boolean类型
    • 表达式1和表达式2为同种类型
    • 三元运算符可嵌套使用
  2. 三元运算符与if-else的联系与区别

    • 三元运算符可简化if-else语句,因此能用三元运算符的地方尽量用三元运算符
    • 三元运算符要求必须返回一个结果
    • if后的代码块可有多个语句
    • 凡是可以使用三元运算符的地方都可以改写成if-else,反之则不一定行
  3. 练习:获取3个数中的最大值

int max1 = (a > b)? a : b;
int max2 = (max1 > c)? max1 : c;

运算符的优先等级

  1. 运算符有不同优先级,所谓优先级就是表达式 运算中的运算顺序

  2. 只有单目运算符、三元运算符、赋值运算符是从右向左运算的

流程控制

  • 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块

如何从键盘/控制台获取不同类型的变量:需要使用Scanner类

  1. 导包:import java.util.Scanner;

  2. Scanner的实例化:Scanner scan = new Scanner(System.in);

  3. 调用Scanner的相关方法,来获取指定类型的变量。

  4. 对于char类型的获取,Scanner没有提供相关的方法,只能获取一个字符串。

  5. 如果一定要获取char类型,可用charAt(0)获取字符串索引为0位置上的字符。

  • 注意:需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配,则出现异常:InputMisMatchException,导致程序中断。容量小的可自动提升;

如何获取随机数

  1. double value = Math.random():返回一个[0.0, 1.0)之间的double型的值。
  • 例:获取[a,b]之间的int型随机数:(int)(Math.random() * (b - a + 1) + a)

流程控制方式结构化程序设计中规定的三种基本流程结构

  1. 顺序结构

    • 程序从上到下逐行执行,中间没有任何判断和跳转
  2. 分支结构

    • 根据条件,选择性地执行某段代码
    • 有if-else和switch-case两种分支语句
  3. 循环结构

    • 根据循环条件,重复性地执行某段代码
    • 有while、do…while、for三种循环语句
    • 注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素

分支语句

if-else结构

  1. 第一种

    if(条件表达式){

    执行表达式

    }

  2. 第二种:二选一

    if(条件表达式){

    执行表达式1

    }else{

    执行表达式2

    }

  3. 第三种:多选一

    if(条件表达式1){

    执行表达式1

    }

    if(条件表达式2){

    执行表达式2

    }

    ……

    else{

    执行表达式n

    }

  4. 使用说明

    • 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量。
    • 语句块只有一条执行语句时,一对{}可以省略,但建议保留
    • if-else语句结构,根据需要可以嵌套使用(一般不超过3层,超过3层未解决则停下来想其他办法)。
    • 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略。
    • 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓。
    • 当多个条件是“包含”关系时,“小上大下 /子上父下”。
    • if (80 < core <= 99)报错原因:前面的(80 < core)的结果为一个boolean类型,boolean类型不能与int类型做大小关系对比。
  5. 针对于条件表达式:

    • 如果多个表达式之间是”互斥“关系(或没有交集的关系),判断和执行语句的上下顺序不影响。

    • 如果多个表达式之间有交集的关系,则需要根据实际情况来决定哪个声明在上面。

    • 如果多个表达式之间有包含关系,通常情况下,需要将范围小的声明在范围大的上面,否则范围小的就没机会执行了。

    • 就近原则

      if (x > 2)
      if(y > 2)
      执行语句1;
      else
      执行语句2;
      //上述语句相当于:
      if (x > 2)
      if(y > 2)
      执行语句1;
      else
      执行语句2;
      //以上误判源于省略了单行执行语句的{},所以尽量不要省略{}

switch-case结构

13Switch-Case

  1. 说明:
  • 根据switch表达式中的值,依次匹配各个case中的常量。一旦配成功,则进入相应的case结构中,调用其执行语句,当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构末尾结束为止。

  • break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构。

  • switch结构中的表达式,只能是如下六种数据类型之一:byte、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)。

  • case之后只能声明常量,尤其不能是一个范围。

  • break关键字是可选的。

  • default:相当于if-else中的else,也是可选的,且default位置是可选的,一般还是写在末尾。

  • 如果switch-case结构中多个case的执行语句相同,则可以考虑进行合并,即写完多行执行语句相同的case以后只写1行执行语句。

  • 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。

  • 写分支结构时,如果既可以使用if-else,又可以使用switch-case(switch中表达式的取值情况不太多),优先选择使用switch-case。原因:switch-case执行效率稍高。

  • 示例:输入日期,返回日期是那一年的第几天。

    import java.util.Scanner;
    class CountDays{
    public static void main(String[] args){
    Scanner input = new Scanner(System.in);
    System.out.print("请输入年份:");
    int year = input.nextInt();
    System.out.print("\n请输入月份:");
    int month = input.nextInt();
    System.out.print("\n请输入日期:");
    int day = input.nextInt();
    int days = 0;
    switch (month){
    case 12:
    days += 30;
    case 11:
    days += 31;
    case 10:
    days += 30;
    case 9:
    days += 31;
    case 8:
    days += 31;
    case 7:
    days += 30;
    case 6:
    days += 31;
    case 5:
    days += 30;
    case 4:
    days += 31;
    case 3:
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
    days += 29;
    }else{
    days += 28;
    }
    case 2:
    days += 31;
    case 1:
    days += day;
    System.out.println("\n" + year +"年" + month + "月" + day + "号是" + year + "年的第" + days + "天。");
    break;
    default:
    System.out.println("\n输入有误!");
    }
    }
    }

循环结构

  1. 在某些条件满足得情况下,反复执行特定代码的功能

  2. 循环语句的四个组成部分

    ①初始化部分(init_statement)

    ②循环条件部分(test_exp)–> boolean类型

    ③循环体部分(body_statement)

    ④迭代部分(alter_statement)

    14LoopStructure

  3. 通常情况下,循环结束都是因为②中循环条件返回了false

    • 循环语句分类

      • for循环
      • 结构
    • for(① ; ② ; ④){

      ​ ③

      }

      执行过程:① -> ② -> ③ -> ④ -> ② -> ③ -> ④ -> ② -> …… -> 直到②不再返回true,跳出循环

    • 例题:遍历100以内的偶数,输出所有偶数的和,输出所有偶数的个数。

      class ErgodicEvenNum{
      public static void main(String[] args){
      int count = 0;
      int sum = 0;
      for (int i = 0; i <= 100; i++){
      if (i % 2 == 0){
      sum += i;
      count += 1;                        
      }
      }
      System.out.println("0-100内偶数有" + count + "个,它们的和为:" + sum);
      }
      }
      //i在for循环内有效,出了for循环就失效了
    • 例题:输入两个正整数m和n,求其最大公约数和最小公倍数。比如,12和20的最大公约数是4,最小公倍数是60。

      • 说明break的作用
      import java.util.Scanner;
      class GetGcdLcm{
      public static void main(String[] args){
      Scanner scan = new Scanner(System.in);
      System.out.print("请输入第一个整数:");
      int m = scan.nextInt();
      System.out.print("\n请输入第二个整数:");
      int n = scan.nextInt();
      int min = (m <= n)? m : n;
      for (int i = min; i > 0; i--){
      if (m % i == 0 && n % i == 0){
      System.out.print("\n" + m + "和" + n + "的最大公约数为" + i + ",");
      break;
      }
      }
      int max = (m >= n)? m : n;
      for (int i = max; i <= m * n; i++){
      if (i % m == 0 && i % n == 0){
      System.out.println("最小公倍数为" + i + "。");
      break;
      }
      }
      }
      }
  4. while循环

    • 结构

    ①初始化部分

    while(②循环条件部分){

    ③循环体部分;

    ④迭代部分;

    }

    执行过程:① -> ② -> ③ -> ④ -> ② -> ③ -> ④ -> ② -> …… ->②

    • 说明
      • 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
      • for循环和while循环可以相互转换
      • for循环和while循环初始化条件的作用范围不同。
      • i 出了while循环后可以继续使用,原因:①初始化部分在循环外。
  5. do-while

    • 结构

      do{

      ③;

      ④;

      }while(②);

      执行过程:① -> ③ -> ④ -> ② -> ③ -> ④ -> ② …… ->②

    • 特点

      • 先执行再判断,至少执行一次循环体。
      • 开发中较少使用do-while,for和while使用较多。
  6. 循环语句综合题:从键盘输入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时,结束程序。

    import java.util.Scanner;
    class CirCom{
    public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    int posNum = 0;
    int negNum = 0;
    while(true){
    int alter = scan.nextInt();
    if (alter > 0){
    posNum += 1;
    }else if (alter < 0){
    negNum += 1;
    }else{
    break;
    }
    }
    System.out.println("输入的正数个数为:" + posNum);
    System.out.println("输入的负数个数为:" + negNum);
    }
    }
    • 说明:
      • while(true)就相当于for(;;)
      • 结束循环的几种方式
        • 循环条件部分返回false;
        • 在循环体中执行break。
  7. 嵌套循环

  • 嵌套循环的使用

    • 嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环。
    • 外层循环:循环结构B。
    • 内层循环:循环结构A。
  • 说明

    • 内层循环结构遍历一遍,只相当于外层循环结构循环一次。
    • 假设外层循环需要执行m次,内层循环需要执行n次,此时内存层循环的循环体需要执行m*n次。
  • 技巧:外层循环控制行数,内层循环控制列数。

  • 例题:九九乘法表

    import java.util.Scanner;
    class MultiTable{
    public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    System.out.println("要打印几行?(1-9)");
    int line = scan.nextInt();
    for (int i = 1; i <= line; i++){
    for (int j = 1; j <= i; j++){
    System.out.print(i + "x" + j + "=" + i * j + " ");
    }
    System.out.println();
    }
    }
    }
    • 100以内所有质数
    import java.util.Scanner;
    class PriNum{
    public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    System.out.println("要打印多少以内的质数?");
    int limtNum = scan.nextInt();
    System.out.println("*********结果*********");
    boolean isPriNum = true;
    for (int i = 2; i <= limtNum; i++){
    for (int j = 2; j < i; j++)        {
    if (i % j ==0){
    isPriNum = false;
    }
    }
    if (isPriNum){
    System.out.println(i);
    }
    isPriNum = true;
    }
    }
    }
    • 优化
    import java.util.Scanner;
    class PriNum{
    public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    System.out.println("要打印多少以内的质数?");
    int limtNum = scan.nextInt();
    System.out.println("*********结果*********");
    long start = System.currentTimeMillis();//获取当前时间距1970-01-01 00:00:00的毫秒数(long型)
    boolean isPriNum = true;
    int count = 0;
    for (int i = 2; i <= limtNum; i++){
    //for (int j = 2; j < i; j++){
    for (int j = 2; j <= Math.sqrt(i); j++){//优化二:一个数如果在2到它本身开方的范围内没有商,则为质数
    if (i % j ==0){
    isPriNum = false;
    break;//优化一:只对本身非质数的自然数是有效的。加break前后对比:20181ms/2174ms = 9.28
    }
    }
    if (isPriNum){
    count += 1;
    }
    isPriNum = true;
    }
    long end = System.currentTimeMillis();
    System.out.println("质数的个数:" + count);
    System.out.println("所花费的时间:" + (start - end));
    //优化前:17916ms 优化一:1629ms 优化二:16ms
    }
    }

特殊关键字的使用

  • break

    • 使用范围:switch-case、循环结构中
    • 循环中使用的作用:结束当前循环
    • 默认跳出包裹此关键字最近的一层循环
    • 结束指定标识的一层循环结构
    label:for (int i = 1; i <= 4; i++){
    for (int j = 1; j <= 10; j++){
    if (j % 4 == 0){
    break label;
    }
    }
    }
  • continue

    • 使用范围:循环结构中

    • 循环中使用的作用:结束当次循环

    • 结束指定标识的一层循环结构的当次循环

      countinue label;

  • 相同点:两个关键字后面不能声明执行语句

  • return

    • 并非专门用于结束循环的,它的的功能是结束一个方法。当一个方法执行到一个return时,这个方法将被结束。
    • 与break、continue不同的是吗,return直接结束整个方法,不管这个return处于多少层循环之内。
  • 补充:衡量一个功能代码的优劣

    • 正确性
    • 可读性
    • 健壮性
    • 高效率与低存储:时间复杂度、空间复杂度(衡量算法的好坏)

章节练习题及面试题

简答题

Java能动态分配数组吗?

答:可以。int i = 12; int[] myInt = new int[i];

我怎么知道数组的长度?

答:.length属性获取。

数组有没有length()这个方法?String有没有length()这个方法?

答:数组没有length()这个方法,有length属性。String有length()这个方法。

Java中的任何数据类型都可以使用System.out.println方法显示:

  1. 对于基本数据类型而言,输出的往往是变量的值;
  2. 对于像数组这一类复杂的数据类型,输出的是其堆空间中存储位置的hashCode值。

操作二位数组的注意点:

  • 操作二维数组不应使用常数来控制维数。具体方法是array.length表示行数,array[row].length来表示row行的列数。这样当数组行数和列数不相等时,代码可以自动调整为正确的值。

编程题

显示输出

String[] stringArray = new String[3];//各元素默认值为null
for(int i = 0;i < stringArray.length;++){//对各元素进行初始化,但没有赋值
stringArray[i] = new String();
System.out.println(stringArray[i]);
}

答:空(有别于null)。

面试题目:创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同。

package top.triabin.chapter02;
/**
*
* @Description 面试题目:创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同。
* @author DawnLee
* @version 1.0
* @data 2020-9-8 17:10:29
*
*/
public class CreateArrays {
public static void main(String[] args) {
int[] array = new int[6];
int count = 0;
while(count < 6) {
int ele = (int)(Math.random() * (30 - 1 + 1) + 1);
boolean isEqual = false;
for(int i = 0;i < count;i++) {
if(array[i] == ele) {
isEqual = true;
}
}
if(isEqual) {
continue;
}else {
array[count++] = ele;
}
}
for(int i = 0;i < array.length;i++) {
System.out.print(array[i] + " ");
}
}
}