当前位置: 首页 > 图灵资讯 > 技术篇> Java 中的运算符和流程控制(附面试题)

Java 中的运算符和流程控制(附面试题)

来源:图灵教育
时间:2023-05-28 09:34:46

算术运算符

Java 算法运算符包括以下几种:

算术运算符

名称

举例

+

加法

1+2=3

-

减法

2-1=1

*

乘法

2*3=6

/

除法

24/8=3

%

求余

24%7=3

++

自增1

int i=1;i++

--

自减1

int i=1;i--

我们这个讲座要重点讲的是 “++” 和 “-”,其他算术操作符相对简单直观,本讲座不需要精力来解释,为什么要解释 “++” 和 “--” 单独拿出来是因为开发者在使用它们时需要注意很多坑。最重要的是 “++” 和 “--” 也是面试中高频出现的面试题。

先来看 “++” 基本使用:

int i = 1;int i2 = ++i; // ++i 相当于 i = 1+i;System.out.println(i);  // 2System.out.println(i2); // 2

++i 和 i++ 的区别

  • ++i 先自加再赋值
  • i++ 先赋值再自加

比如:

int i = 0;int i2 = i++;int j = 0;int j2 = ++j;System.out.println("i2=" + i2);System.out.println("j2=" + j2);

输出结果:

i2=0j2=1

代码解析:i++ 是先给 i2 赋值再自身 +1 ,所以 i2 等于0,而 ++j 是先自加等于 1 之后,再给予赋值 j2,所以 j2 等于 1。

注意事项

++/-- 是非线程安全,也就是说, ++/-- 在多线程下操作可能会引起混乱,如以下代码:

new Thread() {    @Override    public void run() {        for (int i = 0; i < 100000; i++) {            System.out.println("thread:" + this.getName() + ",count=" + (++count));        }    }}.start();new Thread() {    @Override    public void run() {        for (int i = 0; i < 100000; i++) {            System.out.println("thread:" + this.getName() + ",count=" + (++count));        }    }}.start();

执行结果如下:

Java 中的运算符和流程控制(附面试题)_运算符

如上图所示,每台机器的执行可能有一点差距,但在大多数情况下,它不能给我们想要的真实值 200000。

原理分析

“++” 多线程操作造成混乱的原因: ++ 对于底层操作系统来说,操作不是一个条件 CPU 操作指令,但三个 CPU 操作指令-取值、累加、存储,因此不能保证原子性,执行上述代码后会出现误差。

如何避免 ++/-- 多线程下操作的“误差”?

  • 方法1:++//+-- 将操作放在同步块中 synchronized 中。
  • 方法二:自己申明锁,把锁 ++/-- 其中包含了操作。
  • 方法三:使用 AtomicInteger 类型替代 int 类型。

最后,因为 -- 的语法和 ++ 完全一致,所以 -- 请参考上述操作 ++ 语法。

条件运算符(三元运算符)

条件运算符(条件运算符(条件运算符):)又称“三元运算符”。

语法:

布尔表达式 ? 表达式1 :表达式2

如果布尔表达式的值为 true,则返回 表达式 1 值,否则返回 表达式 2 的值。

例如:

String s = 3 > 1 ? “三大于一” : “三小于一”;System.out.println(s);

执行结果:三大于一

流程控制

在 Java 在语言中使用条件句和循环结构来实现过程控制。

1 条件语句

条件句的语法格式:

if(...) ...

括号必须用来判断条件,不能省略。

使用基本用法:

int i = 1;if (i > 1) {    System.out.println(i大于一);} else if (i == 1) {    System.out.println(i等于一);} else {    System.out.println(其他);}

2 循环

while 当条件确定时,执行下一个句子。

while 语法格式:

while(...) ...

使用基本语法:

int i = 0;  while (i < 3) {  System.out.println(++i);}

while 在决定是否执行之前,有可能不执行一次。如果你想至少执行一次,你可以使用它 do/while。

do/while 语法格式:

do{...}while(...);

使用基本语法:

int i = 0;do {  System.out.println(++i);} while (i < 3);

3 确定循环

for 循环是程序中使用最长的循环之一,它使用每次迭代后更新计数器来控制循环次数。

for 语法格式:

for(int i=0;i<n;i++){ ... }

使用基本语法:

for (int i = 0; i < 10; i++) {    System.out.println("i=" + i);}

for 关键词可用于循环 continue,跳过后续操作,继续下一次迭代。

例如:

for (int i = 1; i < 4; i++) {    if (i == 2) continue;    System.out.println("i=" + i);}

执行结果:

i=1i=3

如果结果所示,第二个循环将跳过并执行下一个循环。

for 注意事项

在循环中检查两个浮点数是否相等,例如以下代码:

public static void main(String[] args) {    for (float i = 0; i != 1; i += 0.1) {        System.out.println(i);    }}

循环永远不会停止,因为放弃误差,因为 0.1 不能用二级制准确表示,所以上面的代码到了 0.9000001 之后,会直接跳到 1.000001,不等于 所以循环永远不会停止。

4 多重选择

switch 其特点是可以判断多个条件,if 其特点是执行少量判断,两者正好形成互补关系。

switch 语法格式:

switch(...){ case 1: ... break; ... default: ... break; }

switch 基础使用:

int i = 3;switch (i) {    case 1:        System.out.println(等于1);        break;    case 2:        System.out.println(等于2);        break;    case 3:        System.out.println(等于3);        break;    default:        System.out.println(“等于其他”);        break;}

可用于 case 的类型有:

  • byte、char、short、int
  • 枚举
  • 字符串(Java SE 7 新加入)

switch 注意事项

switch 使用时,不要忘记在每个选项的最后添加 break 关键字,否则会执行多个条件。

案例:

int i = 1;switch (i) {    case 1:        System.out.println(等于1);    case 2:        System.out.println(等于2);    case 3:        System.out.println(等于3);    default:        System.out.println(“等于其他”);}

程序执行结果:

等于1等于2等于3等于其他等于3

所以使用 switch 当时,必须在每个选项的末尾添加 break 关键字。

相关面试题1. Java 中 i++ 和 ++i 有什么区别?

答:i 先赋值再操作;i 先计算再赋值。

示例代码:

int i = 0;int i2 = i++;int j = 0;int j2 = ++j;System.out.println("i2=" + i2);System.out.println("j2=" + j2);

输出结果:i2=0,j2=1

2. 以下代码 i 值是多少?

int i = 0;i = i++;System.out.println(i);

答:i=0

题目分析:因为 Java 虚拟机正在执行 i++ 当时,这个值被赋值了 i,而 i++ 是先赋值再加,所以这个时候 i 收到的结果自然是 0 了。

3. 以下代码 i2 和 i3 值分别是多少?

int i = 0;int i2 = i++;int i3 = ++i;

答:i2=0,i3=2

4. 下面的代码能正常执行吗?

if (true) System.out.println("laowang");

答:可以正常执行,判断条件的括号不能省略,大括号可以省略(作者不建议为了省代码牺牲代码的可读性)。

5. 以下 switch 执行的结果是什么?

int num = 1;switch (num) {    case 0:        System.out.print("0");    case 1:        System.out.print("1");    case 2:        System.out.print("2");    case 3:        System.out.print("3");    default:        System.out.print("default");}

答:123default

6. switch 能否用于 byte 类型的判断?可以用来判断吗? long 判断类型?

答:switch 支持 byte 不支持对类型的判断 long 判断类型。

题目解析:switch 所有类型的支持(JDK 8):char、byte、short、int、Charachter、Byte、Short、Integer、String、enum。

7. while 必须配合 break 一起使用的说法正确吗?

答:错误,while 可单独使用。

例如:

int i = 0;while (i < 3) {    System.out.println(++i);}

8. 以下代码能正常运行吗?为什么?

int i = 0;while (i < 3) {    if (i == 2) {        return;    }    System.out.println(++i);}

答:可以正常运行,这里 return 和 break 效果一致,while 可以配合 return 或 break 一起使用。

9. 以下程序执行结果是什么?

int i = 0;do {  System.out.println(++i);} while (i < 3)

答:编译器报错,do/while 之后必须使用分号 ; 结尾。

10. 以下程序输出的结果是什么?

String s = new String("laowang");String s2 = new String("laowang");System.out.println(s == s2);switch (s) {    case "laowang":        System.out.println("laowang");        break;    default:        System.out.println("default");        break;}

A:true,defaultB:false,defaultC:false,laowangD:true,laowang

答:C

11. 以下代码循环执行了多少次?

for (float i = 0; i != 10; i += 0.1) {    System.out.println("hi");}

答:无数次,循环永远不会停止。因为放弃错误,因为 0.1 不能用二级制准确表示,所以上面的代码到了 0.9000001 之后,会直接跳到 1.000001,不等于 所以循环永远不会停止。

12. 以下代码输出的结果是什么?

int num = -4;System.out.println(num % 2 == 1 || num % 2 == -1);

A:1B:-1C:trueD:false

答:D

题目解析:-4 % 2 = 0 既不等于 1 也不等于 -所以结果是 false。

13. 以下代码输出的结果是什么?

int num = 4;num = ((num & 1) == 1);System.out.println(num);

A:4B:1C:以上都不是

答:C

题目解析:== 运算返回的是 boolean 不能使用类型 int 接收,所以程序会报错。