写在前面:这是JavaSE系列的第3篇。前两篇我们学了环境搭建和数据类型,今天开始学"如何让程序有逻辑"。运算符和流程控制是写代码的骨架。建议边看边敲代码。


在这里插入图片描述

一、Java运算符:让数据动起来

运算符就是对数据进行操作的符号。Java的运算符分为以下几类:

运算符类型 符号 优先级 使用频率
算术运算符 + - * / % ++ -- ⭐⭐⭐⭐⭐
赋值运算符 = += -= *= /= %= ⭐⭐⭐⭐⭐
比较运算符 == != > < >= <= ⭐⭐⭐⭐⭐
逻辑运算符 && ! & ^ ⭐⭐⭐⭐
位运算符 & ^ ~ << >> >>> ⭐⭐⭐
三元运算符 ?: ⭐⭐⭐⭐

1.1 算术运算符

int a = 10;
int b = 3;

System.out.println(a + b);   // 13,加法
System.out.println(a - b);   // 7,减法
System.out.println(a * b);   // 30,乘法
System.out.println(a / b);   // 3,除法(整数除法,小数部分丢弃)
System.out.println(a % b);   // 1,取模(求余数)

⚠️ 整数除法的坑

int x = 5;
int y = 2;
System.out.println(x / y);  // 2,不是2.5!

// 想要小数结果,必须有一个操作数是浮点数
double result = x / 2.0;    // 2.5
// 或者
double result2 = (double)x / y;  // 2.5

++和–(自增自减)

int i = 5;

// ++在前:先自增,后使用
int a = ++i;  // i变成6,然后a=6
System.out.println("a=" + a + ", i=" + i);  // a=6, i=6

// ++在后:先使用,后自增
int b = i++;  // b=6,然后i变成7
System.out.println("b=" + b + ", i=" + i);  // b=6, i=7

// --同理

面试高频题

int i = 1;
i = i++;
System.out.println(i);  // 输出1,不是2!

/*
解释:
1. 先计算i++,返回旧值1
2. 然后i自增变成2
3. 最后把1赋值给i
4. 所以i最终是1
*/

1.2 赋值运算符

int a = 10;  // 基本赋值

// 复合赋值运算符
a += 5;   // 等价于 a = a + 5,a=15
a -= 3;   // 等价于 a = a - 3,a=12
a *= 2;   // 等价于 a = a * 2,a=24
a /= 4;   // 等价于 a = a / 4,a=6
a %= 4;   // 等价于 a = a % 4,a=2

// 面试考点:复合赋值运算符会自动类型转换
byte b = 10;
// b = b + 1;  // 编译错误!b+1结果是int
b += 1;       // 正确,等价于 b = (byte)(b + 1)

1.3 比较运算符

int a = 10;
int b = 20;

System.out.println(a == b);  // false,等于
System.out.println(a != b);  // true,不等于
System.out.println(a > b);   // false,大于
System.out.println(a < b);   // true,小于
System.out.println(a >= b);  // false,大于等于
System.out.println(a <= b);  // true,小于等于

// 结果是boolean类型
boolean result = a > b;  // false

⚠️ 注意:比较运算符不能连着写

// 错误!
// if (5 < x < 10)  // 编译错误

// 正确写法
if (x > 5 && x < 10)

1.4 逻辑运算符

boolean a = true;
boolean b = false;

System.out.println(a && b);  // false,逻辑与(两个都为true才true)
System.out.println(a || b);  // true,逻辑或(有一个为true就true)
System.out.println(!a);      // false,逻辑非(取反)

// 短路特性
int x = 5;
int y = 0;

// &&短路:左边为false,右边不执行
if (x < 0 && (y = 10) > 0) {
    System.out.println("不会执行到这里");
}
System.out.println("y=" + y);  // y还是0,说明(y=10)没执行

// ||短路:左边为true,右边不执行
if (x > 0 || (y = 10) > 0) {
    System.out.println("执行到这里");
}
System.out.println("y=" + y);  // y还是0,说明(y=10)没执行

逻辑运算符对比表

在这里插入图片描述

&和&&的区别

// &:不短路,两边都会执行
// &&:短路,左边为false时右边不执行

// |和||同理
// |:不短路
// ||:短路,左边为true时右边不执行

// 实际应用:防止空指针
String str = null;
// if (str != null & str.length() > 0)  // 会报错,右边还是会执行
if (str != null && str.length() > 0)  // 正确,str为null时右边不执行

1.5 位运算符(面试常考)

int a = 5;   // 二进制:0000 0101
int b = 3;   // 二进制:0000 0011

System.out.println(a & b);   // 1,按位与(同为1才为1)
// 0000 0101
// 0000 0011
// --------
// 0000 0001 = 1

System.out.println(a | b);   // 7,按位或(有1就为1)
// 0000 0101
// 0000 0011
// --------
// 0000 0111 = 7

System.out.println(a ^ b);   // 6,按位异或(不同为1)
// 0000 0101
// 0000 0011
// --------
// 0000 0110 = 6

System.out.println(~a);      // -6,按位取反

System.out.println(a << 1);  // 10,左移1位(相当于乘2)
System.out.println(a >> 1);  // 2,右移1位(相当于除2)
System.out.println(a >>> 1); // 2,无符号右移

位运算的实际应用

// 1. 判断奇偶(比%2快)
int num = 7;
if ((num & 1) == 0) {
    System.out.println("偶数");
} else {
    System.out.println("奇数");
}

// 2. 交换两个数(不用临时变量)
int x = 5, y = 3;
x = x ^ y;
y = x ^ y;  // y变成原来的x
x = x ^ y;  // x变成原来的y
System.out.println("x=" + x + ", y=" + y);  // x=3, y=5

// 3. 乘除2的幂(移位比乘除快)
int n = 16;
System.out.println(n << 3);  // 16 * 8 = 128
System.out.println(n >> 2);  // 16 / 4 = 4

1.6 三元运算符

// 条件 ? 值1 : 值2
// 条件为true返回值1,否则返回值2

int a = 10;
int b = 20;
int max = a > b ? a : b;  // max=20

// 嵌套(不建议嵌套太多层,可读性差)
int score = 85;
String grade = score >= 90 ? "A" : (score >= 80 ? "B" : (score >= 60 ? "C" : "D"));

二、流程控制:让程序有逻辑

2.1 if-else条件判断

int score = 85;

// 基本if
if (score >= 60) {
    System.out.println("及格");
}

// if-else
if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

// if-else if-else(多分支)
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

// 简写(只有一行代码可以省略大括号,但不推荐)
if (score >= 60)
    System.out.println("及格");

⚠️ 常见错误

// 错误!if后面加了分号
if (score >= 60); {
    System.out.println("这行总会执行");
}

// 错误!==写成=
if (a = 5) {  // 编译错误,Java中不能这样写(C语言可以,是bug)
    System.out.println("a等于5");
}

2.2 switch-case多分支选择

int day = 3;

switch (day) {
    case 1:
        System.out.println("星期一");
        break;  // 别忘了break!
    case 2:
        System.out.println("星期二");
        break;
    case 3:
        System.out.println("星期三");
        break;
    case 4:
        System.out.println("星期四");
        break;
    case 5:
        System.out.println("星期五");
        break;
    case 6:
    case 7:
        System.out.println("周末");
        break;
    default:
        System.out.println("无效日期");
}

⚠️ 忘记break的坑

int x = 1;
switch (x) {
    case 1:
        System.out.println("1");
        // 没有break,会继续执行case 2
    case 2:
        System.out.println("2");
        break;
    case 3:
        System.out.println("3");
}
// 输出:
// 1
// 2

Java 12+的switch表达式(新特性)

// 传统写法
String result;
switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        result = "工作日";
        break;
    case 6:
    case 7:
        result = "周末";
        break;
    default:
        result = "无效";
}

// Java 12+ 新写法(更简洁)
String result = switch (day) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "周末";
    default -> "无效";
};

// 甚至可以返回值
int numLetters = switch (day) {
    case 1, 2, 3, 4, 5 -> {
        System.out.println("工作日");
        yield 5;  // 用yield返回值
    }
    case 6, 7 -> {
        System.out.println("周末");
        yield 2;
    }
    default -> 0;
};

2.3 for循环

// 基本for循环
for (int i = 0; i < 5; i++) {
    System.out.println(i);  // 0, 1, 2, 3, 4
}

// 执行顺序:
// 1. int i = 0(初始化,只执行一次)
// 2. i < 5(条件判断)
// 3. 执行循环体
// 4. i++(迭代)
// 5. 回到第2步

// 其他形式
for (int i = 5; i > 0; i--) {  // 倒序
    System.out.println(i);
}

for (int i = 0; i < 10; i += 2) {  // 步长为2
    System.out.println(i);  // 0, 2, 4, 6, 8
}

// 死循环
for (;;) {
    System.out.println("无限循环");
    break;  // 必须加break,否则真的无限循环
}

嵌套for循环

// 打印九九乘法表
for (int i = 1; i <= 9; i++) {
    for (int j = 1; j <= i; j++) {
        System.out.print(j + "*" + i + "=" + (i * j) + "\t");
    }
    System.out.println();  // 换行
}

2.4 while和do-while循环

// while循环:先判断,后执行
int i = 0;
while (i < 5) {
    System.out.println(i);
    i++;
}

// do-while循环:先执行,后判断(至少执行一次)
int j = 0;
do {
    System.out.println(j);
    j++;
} while (j < 5);

// 实际应用:用户输入验证
import java.util.Scanner;

Scanner scanner = new Scanner(System.in);
int num;
do {
    System.out.print("请输入1-100之间的数字:");
    num = scanner.nextInt();
} while (num < 1 || num > 100);
System.out.println("输入有效:" + num);

2.5 增强for循环(for-each)

// 遍历数组
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    System.out.println(num);
}

// 遍历集合
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
    System.out.println(name);
}

// 注意:增强for不能修改数组/集合的元素
for (int num : numbers) {
    num = num * 2;  // 这样写没用,num是副本
}
// 要修改用普通for
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = numbers[i] * 2;
}

2.6 break和continue

// break:跳出整个循环
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;  // i=5时跳出循环
    }
    System.out.println(i);  // 输出0,1,2,3,4
}

// continue:跳过当前迭代,继续下一次
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;  // 跳过偶数
    }
    System.out.println(i);  // 输出1,3,5,7,9
}

// 带标签的break(跳出外层循环)
outer: for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (i == 1 && j == 1) {
            break outer;  // 跳出外层循环
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}

三、综合练习

练习1:判断素数

public static boolean isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i <= Math.sqrt(n); i++) {
        if (n % i == 0) return false;
    }
    return true;
}

练习2:打印菱形

public static void printDiamond(int size) {
    // 上半部分
    for (int i = 1; i <= size; i++) {
        for (int j = 1; j <= size - i; j++) {
            System.out.print(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) {
            System.out.print("*");
        }
        System.out.println();
    }
    // 下半部分
    for (int i = size - 1; i >= 1; i--) {
        for (int j = 1; j <= size - i; j++) {
            System.out.print(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) {
            System.out.print("*");
        }
        System.out.println();
    }
}

练习3:猜数字游戏

import java.util.Scanner;
import java.util.Random;

public class GuessNumber {
    public static void main(String[] args) {
        Random random = new Random();
        int target = random.nextInt(100) + 1;  // 1-100
        Scanner scanner = new Scanner(System.in);
        int guess;
        int count = 0;
        
        System.out.println("猜数字游戏!我想了一个1-100之间的数字。");
        
        do {
            System.out.print("请输入你的猜测:");
            guess = scanner.nextInt();
            count++;
            
            if (guess > target) {
                System.out.println("太大了!");
            } else if (guess < target) {
                System.out.println("太小了!");
            } else {
                System.out.println("恭喜你猜对了!用了" + count + "次");
            }
        } while (guess != target);
    }
}

四、面试高频考点

考点1:i++和++i的区别

int i = 1;
int a = i++;  // a=1, i=2
int b = ++i;  // i=3, b=3

考点2:短路特性

// &&和||的短路特性
// &和|不短路

考点3:switch能用什么类型

  • Java 5之前:byte、short、char、int
  • Java 5:增加枚举
  • Java 7:增加String
  • Java 17:增加模式匹配

考点4:三种循环的选择

循环类型 适用场景 特点
for 知道循环次数 初始化、条件、迭代都在一行,结构清晰
while 不知道次数,可能一次都不执行 先判断后执行
do-while 至少执行一次 先执行后判断

五、总结

今天我们学习了:

  • ✅ 6类运算符:算术、赋值、比较、逻辑、位、三元
  • ✅ 流程控制:if-else、switch、for、while、do-while
  • ✅ break和continue的使用
  • ✅ 3个综合练习

重点记忆

  1. ++i和i++的区别
  2. &&的短路特性
  3. switch的穿透问题(break)
  4. 三种循环的使用场景

下一步预告
Day4我们将深入学习数组和字符串——数组算法、String的常用方法、StringBuilder的使用。


互动话题:你在写循环的时候有没有遇到过死循环?或者switch忘记写break的坑?欢迎在评论区分享!

如果这篇文章对你有帮助,欢迎点赞、收藏!这是【JavaSE全面教学】系列的第3篇,关注我看完整套教程 👇


本文为【JavaSE全面教学】系列第3篇,持续更新中…

更多推荐