关键字与保留字
关键字(keyword)
- 定义:被Java语言赋予特殊含义,用作专门用途的字符(单词)。
- 特点:关键字中所有字母都为小写。
- 官方地址:https://docs.oracle.com/javase/tutorial/java/nutsandbolts.html
保留字(reserved word)
Java保留字:现有的Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字。
- 例:goto、const……
标识符(Identifier)
标识符
- Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
- 比如:类名、变量名、方法名、接口名、包名……
- 技巧:凡是自己可以取名字的地方都叫标识符。
定义合法标识符规则(必须遵守)
- 由26个英文字母大小写,0-9,_或$组成;
- 数字不可开头;
- 不可以使用关键字和保留字,但可以包含关键字和保留字;
- Java中严格区分大小写,长度无限制;
- 标识符不能包含空格。
Java中名称命名规范(建议遵守)
包名:多单词组成时所有字母都小写:xxxyyyzzz;
类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz ;
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz;
常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ;
注意
注意1:在取名字时,为提高阅读性,要尽量有意义(见名知意)
注意2:Java采用unicode字符集,因此标识符也可以使用汉字声明,但不建议使用
变量
变量的概念
内存中的一个存储区域;
该区域的数据可在同一类型范围内不断变化;
变量是程序中最基本的存储单元。包含变量类型(强类型:必须先声明)、变量名和存储的值。
- 定义变量的格式:数据类型 变量名 = 变量值
- 例:
int myAge = 18;
- 例:
- 定义变量的格式:数据类型 变量名 = 变量值
变量的作用
- 用于在内存中保存数据。
变量的使用
- Java中每个变量必须先声明,后使用;
- 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了。“一对{}”即为一个作用域;
- 同一个作用域内,不能声明两个同名的变量。
- 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
- byte
浮点类型
单精度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表示
- boolean
引用数据类型(reference type)
- 类(class)
- 接口(interface)
- 数组([])
数据类型 | 占用存储空间 | 表数范围 | |||
---|---|---|---|---|---|
基本数据类型 | 数值型 | 整数类型 | 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码
在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有0和1两种状态,因此8个二进制位就可以组合出256种状态,这被称为一个字节(byte)。一个字节一共可以用来表示 256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111
ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0
缺点
- 不能表示所有字符
- 相同的编码表示的字符不一样:比如,130在法语编码中代表了é,在希伯来语编码中却代表(ג)了字母Gimel
Unicode编码
乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
Unicode:一种编码方式,将世界上所有的符号都纳入其中。每一个符号都给予一个独一 无二的编码,使用Unicode没有乱码的问题。
Unicode的缺点:
Unicode只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储;
无法区别 Unicode 和ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有 二到三个字节是0,这对于存储空间来说是极大的浪费。
UTF-8
UTF-8是在互联网上使用最广的一种Unicode的实现方式
UTF-8是一种变长的编码方式。它可以使用**1-6个字节**表示一个符号,根据不同的符号而变化字节长度
UTF-8的编码规则
对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)
对于多字节的UTF-8编码,如果编码包含n个字节,那么第一个字节的前n位为1,第一个字节的第n+1位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为”10”,其余6位用来对字符进行编码
Tips:解除转义 例:解除换行符:\\n,直接显示“\n”
基本数据类型之间的运算规则
前提
- 这里只讨论7种基本数据类型变量间的运算,不包含boolean类型的。
自动类型提升
- 容量小的类型自动转换为容量大的数据类型。
- byte、char、short三种类型变量做运算时,结果为int类型,即这三个变量之间的运算结果至少要拿一个int型去接收。原因:可能是防止溢出,并且整形常量默认类型为int型,运算时如果直接加减数字的话编译不通过。
强制类型转换
- 自动类型提升的逆运算:
需要使用强转符
强制类型转换可能导致精度损失
字符串类型:String
String属于引用数据类型;
声明String类型变量时,使用一对双引号(””),长度不限(不超过内存空间即可);
定义String类型变量时,双引号之间可以没有内容,但是char类型不可以;
String可以和8中基本数据类型变量作运算,且运算只能是连接运算(+),运算结果仍是String类型;
将String类型转为int型:
int num1 = Integer.parseInt(str1)
,而不能用强制转换,强制转换只能在上述7种数据类型之间。
进制(了解内容)
- 所有数字在计算机底层都以二进制形式存在
整数的四种表示方式
- 二进制(binary):0,1 ,满2进1,以0b或0B开头;
- 十进制(decimal):0-9 ,满10进1;
- 八进制(octal):0-7 ,满8进1,以数字0开头表示;
- 十六进制(hex):0-9及A-F,满16进1,以0x或0X开头表示。此处的A-F不区分大小写。如:0x21AF + 1 = 0X21B0。
二进制
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位
二进制的整数有如下三种形式:
原码:直接将一个数值换成二进制数。最高位是符号位。
负数的反码:是对原码按位取反,只是最高位(符号位)确定为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,后运算
- (后)++:先运算,后自增1
- 自减(略)
- 注意:自增(减)不会改变变量本身数据类型
赋值运算符(=)
当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理
支持连续赋值
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 |
比较运算符的运算结果都是boolean型,也就是要么是true,要么false
区分“=”和“==”
逻辑运算符
参数 | 参数 | 逻辑与 | 短路与 | 逻辑或 | 短路或 | 逻辑非 | 逻辑异或 |
---|---|---|---|---|---|---|---|
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 |
区分逻辑与(&)和短路与(&&)
- 相同点:运算结果相同;党符号左边为true时,都会执行符号右边的内容
- 不同点:当左边为false时,&&不会执行符号右边的运算(短路)
- 开发中优先使用短路与(&&)
区分逻辑或(|)和短路或(||)
- 相同点:运算结果相同;当符号右边为false时,二者都会执行符号右边的内容
- 不同点:当符号左边为true时,|| 不会执行符号右边的运算(短路)
- 开发中优先使用短路或(||)
逻辑非(!)
逻辑异或(^)
- 相同为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。 |
~ | 正数取反,各二进制码按补码各位取反;负数取反,各二进制码按补码各位取反。 |
位运算符是直接对整数的二进制进行的运算
位运算符操作的都是整形的数据
<<:在一定范围内,每向左移n位,相当于*2n
>>:在一定范围内,每向右移n位,相当于/2n
面试题:如何最高效的计算2*8?
- 2 << 3 或 8 << 1
注意:无<<<
&、|、^运算
~取反运算
- 包括符号位在内取反
练习:交换两个变量的值
方法一:定义临时变量
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;
三元运算符
格式:
- 条件表达式的结果为boolean类型
- 表达式1和表达式2为同种类型
- 三元运算符可嵌套使用
三元运算符与if-else的联系与区别
- 三元运算符可简化if-else语句,因此能用三元运算符的地方尽量用三元运算符
- 三元运算符要求必须返回一个结果
- if后的代码块可有多个语句
- 凡是可以使用三元运算符的地方都可以改写成if-else,反之则不一定行
练习:获取3个数中的最大值
int max1 = (a > b)? a : b; |
运算符的优先等级
运算符有不同优先级,所谓优先级就是表达式 运算中的运算顺序
只有单目运算符、三元运算符、赋值运算符是从右向左运算的
流程控制
- 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块
如何从键盘/控制台获取不同类型的变量:需要使用Scanner类
导包:
import java.util.Scanner;
Scanner的实例化:
Scanner scan = new Scanner(System.in);
调用Scanner的相关方法,来获取指定类型的变量。
对于char类型的获取,Scanner没有提供相关的方法,只能获取一个字符串。
如果一定要获取char类型,可用charAt(0)获取字符串索引为0位置上的字符。
- 注意:需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配,则出现异常:InputMisMatchException,导致程序中断。容量小的可自动提升;
如何获取随机数
double value = Math.random()
:返回一个[0.0, 1.0)之间的double型的值。
- 例:获取[a,b]之间的int型随机数:
(int)(Math.random() * (b - a + 1) + a)
流程控制方式结构化程序设计中规定的三种基本流程结构
顺序结构
- 程序从上到下逐行执行,中间没有任何判断和跳转
分支结构
- 根据条件,选择性地执行某段代码
- 有if-else和switch-case两种分支语句
循环结构
- 根据循环条件,重复性地执行某段代码
- 有while、do…while、for三种循环语句
- 注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素
分支语句
if-else结构
第一种
if(条件表达式){
执行表达式
}
第二种:二选一
if(条件表达式){
执行表达式1
}else{
执行表达式2
}
第三种:多选一
if(条件表达式1){
执行表达式1
}
if(条件表达式2){
执行表达式2
}
……
else{
执行表达式n
}
使用说明
- 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量。
- 语句块只有一条执行语句时,一对{}可以省略,但建议保留
- if-else语句结构,根据需要可以嵌套使用(一般不超过3层,超过3层未解决则停下来想其他办法)。
- 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略。
- 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓。
- 当多个条件是“包含”关系时,“小上大下 /子上父下”。
- if (80 < core <= 99)报错原因:前面的(80 < core)的结果为一个boolean类型,boolean类型不能与int类型做大小关系对比。
针对于条件表达式:
如果多个表达式之间是”互斥“关系(或没有交集的关系),判断和执行语句的上下顺序不影响。
如果多个表达式之间有交集的关系,则需要根据实际情况来决定哪个声明在上面。
如果多个表达式之间有包含关系,通常情况下,需要将范围小的声明在范围大的上面,否则范围小的就没机会执行了。
就近原则
if (x > 2)
if(y > 2)
执行语句1;
else
执行语句2;
//上述语句相当于:
if (x > 2)
if(y > 2)
执行语句1;
else
执行语句2;
//以上误判源于省略了单行执行语句的{},所以尽量不要省略{}
switch-case结构
- 说明:
根据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输入有误!");
}
}
}
循环结构
在某些条件满足得情况下,反复执行特定代码的功能
循环语句的四个组成部分
①初始化部分(init_statement)
②循环条件部分(test_exp)–> boolean类型
③循环体部分(body_statement)
④迭代部分(alter_statement)
通常情况下,循环结束都是因为②中循环条件返回了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;
}
}
}
}
while循环
- 结构
①初始化部分
while(②循环条件部分){
③循环体部分;
④迭代部分;
}
执行过程:① -> ② -> ③ -> ④ -> ② -> ③ -> ④ -> ② -> …… ->②
- 说明
- 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
- for循环和while循环可以相互转换
- for循环和while循环初始化条件的作用范围不同。
- i 出了while循环后可以继续使用,原因:①初始化部分在循环外。
do-while
结构
①
do{
③;
④;
}while(②);
执行过程:① -> ③ -> ④ -> ② -> ③ -> ④ -> ② …… ->②
特点
- 先执行再判断,至少执行一次循环体。
- 开发中较少使用do-while,for和while使用较多。
循环语句综合题:从键盘输入个数不确定的整数,并判断读入的正数和负数的个数,输入为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。
- 说明:
嵌套循环
嵌套循环的使用
- 嵌套循环:将一个循环结构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方法显示:
- 对于基本数据类型而言,输出的往往是变量的值;
- 对于像数组这一类复杂的数据类型,输出的是其堆空间中存储位置的hashCode值。
操作二位数组的注意点:
- 操作二维数组不应使用常数来控制维数。具体方法是array.length表示行数,array[row].length来表示row行的列数。这样当数组行数和列数不相等时,代码可以自动调整为正确的值。
编程题
显示输出
String[] stringArray = new String[3];//各元素默认值为null |
答:空(有别于null)。
面试题目:创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同。
package top.triabin.chapter02; |