内容预览
- 运算符
- java的条件语句、循环语句
- 方法定义与方法重载、可变参数
- 递归的简单应用
一、运算符
运算符分类
java语言支持以下运算符:
- 算术运算符:
+
,-
,*
,/
,%
,++
,--
- 赋值运算符:
=
- 扩展赋值运算符:
+=
,-=
,*=
,/=
- 字符串连接符:
+
- 关系(比较)运算符:
>
,<
,==
,>=
,<=
,!=
- 逻辑运算符:
&
,|
,!
,^
,&&
,||
- 位运算符:
&
,|
,^
,~
,<<
,>>
,>>>
- 三目运算符:
x ? y :z
算术运算符(自增自减运算符)
来看一段代码:
public class Demo1Operator {
public static void main(String[] args){
int i;
int i1 = 10;
int i2 = 20;
i = (i2++);
System.out.println("i = " + i); // 输出结果:i = 20
System.out.println("i2= " + i2); // 输出结果:i2= 21
System.out.println("===================我是分割线========================");
i = (++i2);
System.out.println("i = " + i); // 输出结果:i = 22
System.out.println("i2= " + i2); // 输出结果:i2= 22
System.out.println("===================我是分割线========================");
i = (i1--);
System.out.println("i = " + i); // 输出结果:i = 10
System.out.println("i1= " + i1); // 输出结果:i1= 9
System.out.println("===================我是分割线========================");
i = (--i1);
System.out.println("i = " + i); // 输出结果:i = 8
System.out.println("i1= " + i1); // 输出结果:i1= 8
System.out.println("===================我是分割线========================");
}
}
注意:
-
++在前时先运算,再取值。如 ++i, (先i+1;再取值),即(运算;取值)
-
++在后时先取值,再运算。如 i++, (先取值;再i+1),即(取值;运算)
-
两个整数做除法会自动舍弃小数部分。需要考虑到两个整数相除,结果为小数的情况,将其中一个数强制转换为 double 类型即可解决。
-
取模结果是正是负:和被模数的正负一致,与模数无关。
int result = (-5) % 2; // 输出结果为 -1 int result = (5) % (-2) // 输出结果为 1
赋值运算符
-
当“=”两侧数据类型不一致时,可以适当运用默认类型转换或者强制类型转换原则进行处理
long l = 100; int i = (int) l;
-
可以将整型常量直接赋值给byte,short,char等类型变量,而不需要进行强制类型转换,只要不超过其范围。
// 正确示范一: byte b = 12; // 正确示范二: char c = 100; // 错误示范一: byte bb = 256; // 错误示范二: short s = -32769;
-
扩展赋值运算符具有强制类型转换的效果
public class Demo2Operator { public static void main(String[] args){ short shortValue = 10; short shortValue1 = 20; //shortValue = shortValue + shortValue1; // 错误: 不兼容的类型: 从int转换到short可能会有损失 shortValue += shortValue1; System.out.println("shortValue = " + shortValue); // 输出结果为30 } }
运算符 用法举例 等效表达式 += a += b a = a + b -= a -= b a = a - b
练习
练习一:
public class Demo01Operator{
public static void main(String[] args){
int n = 10;
/*
分析:
n = n + (n++) + (++n);
n = 10 + 10 + 12
*/
n += (n++) + (++n);
System.out.println(n); // 32
}
}
练习二:
public class Demo02Operator{
public static void main(String[] args){
int i = 1;
int j = i++; // j = 1; i = 2;
int k = i++ * ++j + ++i * j++;
// k = 2 * 2 + 4 * 2
System.out.println("i = " + i); // 4
System.out.println("j = " + j); // 3
System.out.println("k = " + k); // 12
}
}
字符串连接符
-
“+”除用于算术加法运算外,还可用于对字符串进行连接操作
// 加法运算 int i = 100 + 80; // 字符串连接 String str = "hello" + "world"; System.out.println(str); // 输出结果为:helloworld
-
“+”运算符两侧的操作数中只要有一个是字符串( String)类型,系统会自动将另个操作数转换为字符串然后再进行连接。
int c = 12; System.out.println("c = " + c); // 输出结果为:c = 12
逻辑运算符
逻辑运算符:
! —— 逻辑非 & —— 逻辑与 | —— 逻辑或 ^ —— 逻辑异或 && ——短路与 || —— 短路或
a | b | !a | a & b | a | b | a ^ b | a && b | a || b |
---|---|---|---|---|---|---|---|
true | true | false | true | true | false | true | true |
true | false | false | false | true | true | false | true |
false | true | true | false | true | false | false | true |
false | false | true | false | false | true | false | false |
位运算符
运算符 | 运算 | 范例 |
---|---|---|
<< | 左移 | 3 << 2 = 12 --> 3*2*2=12 |
>> | 右移 | 3 >> 1 = 1 --> 3/2=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 |
~ | 正数取反,各二进制码按补码各位取反负数取反,各二进制码按补码各位取反 |
表达式
三目运算符
三目运算符格式:x ? y : z
-
其中 x 为 boolean 类型表达式,先计算 表达式 x 的值,若为 true ,则整个三目运算符的运算结果为 表达式 y 的值 ,否则整个运算结果为表达式 z 的值。
-
最终的结果需要有变量接收。
// 正确示例 int result = ( 3 > 2) ? 1 :0; // 错误示例 (3 > 2)? 1 :0;
-
举例:
public class Demo3Operator{ public static void main (String[] args){ int source = 80; int x = -100; String type = (source > 60) ? "及格" : "不及格"; int flag = (x > 0) ? 1 : (x == 0 ? 0 : -1); System.out.println("type = " + type); // 输出结果:type = 及格 System.out.println("flag = " + flag); // 输出结果:flag = -1 } }
二、语句
语句的分类
- 顺序语句
- 条件语句:if语句,switch语句(分支语句)
- 循环语句:for循环语句,while循环语句,do...while循环语句
条件语句
if语句
if语句格式:
if...
if...else...
if...else if... else...
if...else if... else if...else
- 建议即使只有一条语句,也应该把“{}”加上去,这样可以避免出现不必要的错误。
switch分支语句
格式:
switch(表达式){
case 常量1:
...
break;
case 常量2:
...
break;
default:
...
}
- switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0)
- case子句中的值必须是常量,不能是变量名或不确定的表达式值;
- 同一个switch语句,所有case子句中的常量值互不相同
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有break,程序会顺序执行到switch结尾
- default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时,执行default
举例:
public class Demo4Operator{
public static void main(String[] args){
int i = 8;
switch(i){
case 8:
System.out.println("这是8的分支,但是没有设置break语句,造成case穿透1次");
case 3:
System.out.println("这是3的分支,但是没有设置break语句,造成case穿透2次");
case 2:
System.out.println("这是2的分支,设置了break语句,程序从这里结束了。");
break;
case 9:
System.out.println("这是9的分支,打印字符C");
break;
default:
System.out.println("error");
}
}
}
if语句与switch语句的对比
if和switch语句很像,具体什么场景下,应用哪个语句呢?
- 如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高。
- 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。也就是说,使用switch-case的,都可以改写为if-else。反之不成立。
- 可以利用switch的case穿透性质,求一些累加和,比如说求“从键盘分别输入年、月、日,判断这一天是当年的第几天”案例。
循环语句
for循环语句
1、格式:
for(表达式1;表达式2;表达式3){语句...}
2、执行过程
首先计算表达式1,接着执行表达式2,若表达式2的值=true,则执行语句,接着计算表达式3,再判断表达式2的值;依此重复下去,直到表达式2的值 = false。
- for语句中三个表达式都可以省略
while循环和do...while循环
break和continue语句
- break语句用在循环体系中,为退出当前循环结构。使用范围:switch语句或循环结构中。
- continue语句用在循环体系中,为退出本次循环过程,然后开始下一次循环过程。使用范围:循环语句。
三、方法
方法概述
Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,声明格式:
[修饰符1 修饰符2 ...] 返回值类型 方法名(形参列表){ java语句...}
-
形式参数:在方法被调用时用于接收外界输入的数据。
-
实参:调用方法时实际传给方法的数据。
-
返回值:方法在执行完毕后返还给调用它的环境的数据。
-
返回值类型:事先约定的返回值的数据类型,如无返回值,必须给出返回值类型void.
-
Java语言中使用下述形式调用方法:对象名.方法名(实参列表)
-
实参的数目、数据类型和次序必须和所调用方法声明的形参列表匹配,
-
return语句终止方法的运行并指定要返回的数据。
-
Java进行函数调用中传递参数时,遵循值传递的原则:
基本类型传递的是该数据值本身。引用类型传递的是对对象的引用,而不是对象本身。
方法重载
在Java中,同一个类中的多个方法可以有相同的方法名称,但是有不同的参数列表,这就称为方法重载(method overloading)。
参数列表又叫参数签名,包括参数的类型、参数的个数、参数的顺序,只要有一个不同就叫做参数列表不同。
重载是面向对象的一个基本特性。
public class Student{
//一个普通的方法,不带参数,无返回值
public void study(){
//method body
}
//重载上面的方法,并且带了一个String类型参数,无返回值
public void study(String str){
//method body
}
//重载上面的方法,并且带了两个String类型参数,返回值为String型
public String study(String str1,String str2){
String str = "我爱学习";
//method body
return str;
}
}
通过上面的例子,不难看出,重载就是在一个类中,有相同的函数名称,但形参不同的函数。因此方法重载只需要关注方法的方法名与方法的参数列表。
说明:
- 参数列表不同包括:个数不同、顺序不同、类型不同。
- 仅仅参数变量名称不同是不可以的。
- 跟成员方法一样,构造方法也可以重载。
- 声明为final的方法不能被重载。
- 声明为static的方法不能被重载,但是能够被在此声明。
方法重载的规则:
- 方法名称必须相同。
- 参数列表必须不同。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以称为方法的重载。
可变参数
1、可变参数概念
JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量
2、说明:
① 声明格式:方法名(参数的类型名... 参数名)
② 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
③ 可变个数形参的方法与同名的方法之间,彼此构成重载
④ 可变参数方法的使用与方法参数部分使用数组是一致的
⑤ 方法的参数部分有可变形参,需要放在形参声明的最后
⑥ 在一个方法的形参位置,最多只能声明一个可变个数形参
3、举例
public void test(String[] msg){
System.out.println(“含字符串数组参数的test方法 ");
}
public void test1(String book){
System.out.println(“****与可变形参方法构成重载的test1方法****");
}
public void test1(String ... books){
System.out.println("****形参长度可变的test1方法****");
}
public static void main(String[] args){
TestOverload to = new TestOverload();
//下面两次调用将执行第二个test方法
to.test1();
to.test1("aa" , "bb");
//下面将执行第一个test方法
to.test(new String[]{"aa"});
}
四、递归
递归的概念:在一个方法内部对自身的调用就称为递归
举例:
/*计算第5个斐波那契数列数*/
/*
斐波那契数列特点:f(1)=1,f(2)=1,f(3)=f(1)+f(2),f(4)=(f2)+(f3)……依次类推。
即后一个数都是等于前两个数的和,这样的数列就是斐波那契数列。
*/
/*
使用递归调用的方法计算
*/
public class Fab{
public static void main(String args[]){
System.out.println(f(5));
}
public static int f(int n){
if(n==1||n==2){
return 1;
}else{
return f(n-1)+f(n-2);
}
}
}
整个在内存中执行过程如下图所示