第二章:Java核心语法
在第一章中,我们学习了Java的基础知识,包括如何搭建开发环境、编写第一个Java程序以及基本语法规则。现在,我们将深入学习Java的核心语法,这些语法是构建复杂程序的基础。本章将通过生活中的例子,帮助你轻松理解这些概念。
1. 条件语句(if-else, switch)
1.1 if-else语句
在日常生活中,我们经常需要根据不同情况做出不同决定。比如:如果下雨了,我就带伞;否则,我就不带伞。这种逻辑在编程中可以用if-else语句表示。
基本语法
if (条件) {
// 条件为真时执行的代码
} else {
// 条件为假时执行的代码
}
生活例子:天气决策
public class WeatherDecision {
public static void main(String[] args) {
boolean isRaining = true; // 假设现在正在下雨
if (isRaining) {
System.out.println("带伞出门");
} else {
System.out.println("不用带伞");
}
}
}
多重if-else语句
有时候我们需要检查多个条件,可以使用if-else if-else结构:
public class TemperatureAdvice {
public static void main(String[] args) {
int temperature = 25; // 假设当前温度为25度
if (temperature > 30) {
System.out.println("天气炎热,记得防晒");
} else if (temperature > 20) {
System.out.println("天气适宜,适合户外活动");
} else if (temperature > 10) {
System.out.println("天气凉爽,带件外套");
} else {
System.out.println("天气寒冷,注意保暖");
}
}
}
1.2 switch语句
switch语句适用于针对一个变量有多种可能值的情况,类似于生活中的分类处理。
基本语法
switch (表达式) {
case 值1:
// 当表达式等于值1时执行的代码
break;
case 值2:
// 当表达式等于值2时执行的代码
break;
// 更多case...
default:
// 当表达式不等于任何case值时执行的代码
}
生活例子:星期安排
public class WeeklySchedule {
public static void main(String[] args) {
int dayOfWeek = 3; // 假设今天是星期三
switch (dayOfWeek) {
case 1:
System.out.println("星期一:开始新的一周,列出本周计划");
break;
case 2:
System.out.println("星期二:学习Java基础");
break;
case 3:
System.out.println("星期三:学习Java核心语法");
break;
case 4:
System.out.println("星期四:做Java练习题");
break;
case 5:
System.out.println("星期五:复习本周内容");
break;
case 6:
case 7:
System.out.println("周末:休息或做个人项目");
break;
default:
System.out.println("输入的日期有误");
}
}
}
注意:在Java 12及以上版本中,switch语句有了新的简化语法(switch表达式),但作为初学者,掌握传统语法更为重要。
2. 循环结构(for, while, do-while)
循环结构允许我们重复执行某段代码,就像生活中的重复动作,如每天刷牙、每周购物等。
2.1 for循环
for循环通常用于已知重复次数的情况。
基本语法
for (初始化; 条件; 更新) {
// 循环体
}
生活例子:倒计时
public class Countdown {
public static void main(String[] args) {
System.out.println("开始倒计时:");
for (int i = 10; i >= 1; i--) {
System.out.println(i);
}
System.out.println("新年快乐!");
}
}
2.2 while循环
while循环适用于不确定重复次数,但知道结束条件的情况。
基本语法
while (条件) {
// 循环体
}
生活例子:存钱罐
public class PiggyBank {
public static void main(String[] args) {
double savings = 0;
double target = 1000;
double weeklyDeposit = 150;
int weeks = 0;
while (savings < target) {
savings += weeklyDeposit;
weeks++;
System.out.println("第" + weeks + "周:存款总额为" + savings + "元");
}
System.out.println("恭喜!经过" + weeks + "周的努力,你已经存到" + savings + "元。");
}
}
2.3 do-while循环
do-while循环至少执行一次循环体,然后再检查条件。
基本语法
do {
// 循环体
} while (条件);
生活例子:点菜系统
import java.util.Scanner;
public class OrderSystem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char choice;
do {
System.out.println("\n欢迎使用点菜系统");
System.out.println("1. 牛肉面 - 25元");
System.out.println("2. 宫保鸡丁 - 30元");
System.out.println("3. 水煮鱼 - 45元");
System.out.println("请选择您要点的菜品编号:");
int dishNumber = scanner.nextInt();
switch (dishNumber) {
case 1:
System.out.println("您点了牛肉面,价格25元");
break;
case 2:
System.out.println("您点了宫保鸡丁,价格30元");
break;
case 3:
System.out.println("您点了水煮鱼,价格45元");
break;
default:
System.out.println("对不起,没有此菜品");
}
System.out.println("是否继续点菜?(Y/N)");
choice = scanner.next().charAt(0);
} while (choice == 'Y' || choice == 'y');
System.out.println("谢谢使用,祝您用餐愉快!");
scanner.close();
}
}
3. 数组(一维数组、多维数组)
数组是存储同类型数据的容器,就像生活中的鞋柜、书架等,可以有序地存放多个物品。
3.1 一维数组
基本语法
// 声明数组
数据类型[] 数组名;
// 创建数组
数组名 = new 数据类型[长度];
// 或者一步完成
数据类型[] 数组名 = new 数据类型[长度];
// 初始化数组
数据类型[] 数组名 = {值1, 值2, 值3, ...};
生活例子:学生成绩管理
public class StudentScores {
public static void main(String[] args) {
// 创建一个存储5名学生成绩的数组
int[] scores = {85, 92, 78, 90, 88};
// 计算平均分
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
double average = (double) sum / scores.length;
// 找出最高分
int highest = scores[0];
for (int i = 1; i < scores.length; i++) {
if (scores[i] > highest) {
highest = scores[i];
}
}
System.out.println("学生成绩:");
for (int i = 0; i < scores.length; i++) {
System.out.println("学生" + (i + 1) + ": " + scores[i]);
}
System.out.println("平均分:" + average);
System.out.println("最高分:" + highest);
}
}
3.2 多维数组
多维数组可以看作是"数组的数组",类似于生活中的表格、座位表等。
基本语法
// 声明二维数组
数据类型[][] 数组名;
// 创建二维数组
数组名 = new 数据类型[行数][列数];
// 或者一步完成
数据类型[][] 数组名 = new 数据类型[行数][列数];
// 初始化二维数组
数据类型[][] 数组名 = {
{第一行值1, 第一行值2, ...},
{第二行值1, 第二行值2, ...},
...
};
生活例子:电影院座位
public class MovieTheater {
public static void main(String[] args) {
// 创建一个5行8列的电影院座位表,true表示已售出,false表示空闲
boolean[][] seats = {
{true, true, false, false, true, true, true, false},
{false, true, true, false, false, true, false, true},
{true, false, false, true, true, true, false, false},
{false, false, true, true, false, false, true, false},
{true, true, true, false, true, false, false, true}
};
// 统计空闲座位数量
int availableSeats = 0;
for (int i = 0; i < seats.length; i++) {
for (int j = 0; j < seats[i].length; j++) {
if (!seats[i][j]) {
availableSeats++;
}
}
}
// 显示座位表
System.out.println("电影院座位表(X表示已售出,O表示空闲):");
for (int i = 0; i < seats.length; i++) {
System.out.print("第" + (i + 1) + "排:");
for (int j = 0; j < seats[i].length; j++) {
if (seats[i][j]) {
System.out.print("X ");
} else {
System.out.print("O ");
}
}
System.out.println(); // 换行
}
System.out.println("空闲座位数量:" + availableSeats);
}
}
4. 字符串处理(String类)
字符串是Java中最常用的数据类型之一,用于存储文本信息。在Java中,字符串是不可变的,这意味着一旦创建,其内容不能被修改。
4.1 字符串的创建与基本操作
基本语法
// 创建字符串
String 变量名 = "字符串内容";
// 字符串连接
String 新字符串 = 字符串1 + 字符串2;
// 获取字符串长度
int 长度 = 字符串.length();
// 获取字符串中的字符
char 字符 = 字符串.charAt(索引);
生活例子:个人名片生成器
public class BusinessCardGenerator {
public static void main(String[] args) {
// 创建个人信息字符串
String name = "张三";
String title = "Java开发工程师";
String company = "ABC科技有限公司";
String phone = "13812345678";
String email = "zhangsan@example.com";
// 使用字符串连接生成名片
String businessCard = "姓名: " + name + "\n" +
"职位: " + title + "\n" +
"公司: " + company + "\n" +
"电话: " + phone + "\n" +
"邮箱: " + email;
// 打印名片
System.out.println("===== 个人名片 =====");
System.out.println(businessCard);
System.out.println("===================");
// 获取并显示名片信息的统计数据
int totalLength = businessCard.length();
int nameLength = name.length();
char firstChar = name.charAt(0);
System.out.println("\n名片信息统计:");
System.out.println("名片总字符数: " + totalLength);
System.out.println("姓名长度: " + nameLength);
System.out.println("姓氏首字符: " + firstChar);
}
}
4.2 常用字符串方法
常用方法列表
// 字符串比较
boolean 结果 = 字符串1.equals(字符串2); // 区分大小写
boolean 结果 = 字符串1.equalsIgnoreCase(字符串2); // 不区分大小写
// 字符串查找
int 位置 = 字符串.indexOf(子字符串); // 返回首次出现的位置,未找到返回-1
// 字符串截取
String 子串 = 字符串.substring(开始索引); // 从开始索引到结束
String 子串 = 字符串.substring(开始索引, 结束索引); // 从开始索引到结束索引(不包含)
// 字符串替换
String 新字符串 = 字符串.replace(旧字符串, 新字符串);
// 字符串分割
String[] 数组 = 字符串.split(分隔符);
// 去除首尾空格
String 新字符串 = 字符串.trim();
// 转换大小写
String 大写 = 字符串.toUpperCase();
String 小写 = 字符串.toLowerCase();
生活例子:短信处理系统
public class SMSProcessor {
public static void main(String[] args) {
// 模拟收到的短信
String message = " 【招商银行】尊敬的客户,您的信用卡(尾号1234)于2023-05-15消费了500.00元。详情请登录APP查询。退订回复TD ";
// 1. 去除首尾空格
message = message.trim();
System.out.println("去除空格后:" + message);
// 2. 提取发送方
int startIndex = message.indexOf("【");
int endIndex = message.indexOf("】");
String sender = "未知";
if (startIndex != -1 && endIndex != -1) {
sender = message.substring(startIndex + 1, endIndex);
}
System.out.println("发送方:" + sender);
// 3. 提取卡号尾数
startIndex = message.indexOf("尾号");
String cardNumber = "未知";
if (startIndex != -1) {
cardNumber = message.substring(startIndex + 2, startIndex + 6);
}
System.out.println("卡号尾数:" + cardNumber);
// 4. 提取消费金额
startIndex = message.indexOf("消费了");
endIndex = message.indexOf("元");
String amount = "未知";
if (startIndex != -1 && endIndex != -1) {
amount = message.substring(startIndex + 3, endIndex);
}
System.out.println("消费金额:" + amount);
// 5. 替换敏感信息用于显示
String maskedMessage = message.replace(cardNumber, "****");
System.out.println("\n脱敏后的短信:\n" + maskedMessage);
// 6. 检查是否包含退订信息
boolean containsUnsubscribeInfo = message.toLowerCase().contains("退订");
System.out.println("\n是否包含退订信息:" + containsUnsubscribeInfo);
}
}
5. 包装类
包装类是将Java的基本数据类型转换为对象的类。每个基本数据类型都有对应的包装类,这使得基本类型可以在需要对象的场合使用。
5.1 基本数据类型与包装类的对应关系
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
5.2 自动装箱与拆箱
自动装箱(Autoboxing)是将基本数据类型自动转换为对应的包装类对象;自动拆箱(Unboxing)是将包装类对象自动转换为对应的基本数据类型。
基本语法
// 自动装箱
Integer num = 100; // 自动将int类型的100装箱为Integer对象
// 自动拆箱
int value = num; // 自动将Integer对象拆箱为int类型
生活例子:购物车系统
import java.util.ArrayList;
public class ShoppingCart {
public static void main(String[] args) {
// 创建一个购物车(ArrayList只能存储对象,不能直接存储基本数据类型)
ArrayList<Double> cart = new ArrayList<>();
// 添加商品价格到购物车(自动装箱:double -> Double)
cart.add(29.9); // 自动装箱
cart.add(99.5); // 自动装箱
cart.add(199.0); // 自动装箱
// 显示购物车中的商品
System.out.println("购物车商品价格:");
for (int i = 0; i < cart.size(); i++) {
System.out.println("商品" + (i + 1) + ": " + cart.get(i) + "元");
}
// 计算总价(自动拆箱:Double -> double)
double total = 0;
for (Double price : cart) {
total += price; // 自动拆箱
}
System.out.println("\n商品总价:" + total + "元");
// 使用包装类的方法
double maxPrice = Double.MIN_VALUE;
for (Double price : cart) {
maxPrice = Double.max(maxPrice, price); // 使用Double类的静态方法
}
System.out.println("最贵的商品价格:" + maxPrice + "元");
// 字符串转换为数值(包装类的静态方法)
String discountStr = "0.85";
double discount = Double.parseDouble(discountStr);
double finalPrice = total * discount;
System.out.println("打折后总价(" + (discount * 100) + "%折扣):" + finalPrice + "元");
}
}
5.3 包装类的常用方法
包装类提供了许多有用的方法,如类型转换、值比较等。
常用方法示例
public class WrapperClassMethods {
public static void main(String[] args) {
// Integer类方法示例
int num1 = Integer.parseInt("123"); // 字符串转int
System.out.println("字符串转int: " + num1);
String binaryString = Integer.toBinaryString(10); // 十进制转二进制字符串
System.out.println("10的二进制表示: " + binaryString);
int max = Integer.max(100, 200); // 找出最大值
System.out.println("100和200中的最大值: " + max);
// Double类方法示例
double num2 = Double.parseDouble("123.45"); // 字符串转double
System.out.println("字符串转double: " + num2);
boolean isNaN = Double.isNaN(0.0/0.0); // 检查是否为非数字
System.out.println("0.0/0.0是否为非数字: " + isNaN);
// Boolean类方法示例
boolean bool = Boolean.parseBoolean("true"); // 字符串转boolean
System.out.println("字符串转boolean: " + bool);
// Character类方法示例
char ch = 'A';
boolean isDigit = Character.isDigit(ch); // 检查是否为数字
System.out.println("'A'是否为数字: " + isDigit);
boolean isLetter = Character.isLetter(ch); // 检查是否为字母
System.out.println("'A'是否为字母: " + isLetter);
char lowercase = Character.toLowerCase(ch); // 转换为小写
System.out.println("'A'的小写形式: " + lowercase);
}
}
6. 枚举类型
枚举类型是一种特殊的数据类型,它允许变量只能取特定集合中的预定义值。枚举可以使代码更加可读、安全,并且易于维护。
6.1 枚举的基本用法
基本语法
// 定义枚举类型
enum 枚举名 {
枚举常量1, 枚举常量2, 枚举常量3, ...
}
// 使用枚举
枚举名 变量名 = 枚举名.枚举常量;
生活例子:季节服装选择
public class SeasonalClothing {
// 定义季节枚举
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
public static void main(String[] args) {
// 当前季节
Season currentSeason = Season.SUMMER;
// 根据季节推荐服装
System.out.println("当前季节:" + currentSeason);
System.out.println("推荐服装:");
switch (currentSeason) {
case SPRING:
System.out.println("- 轻薄外套");
System.out.println("- 长袖T恤");
System.out.println("- 休闲裤");
break;
case SUMMER:
System.out.println("- 短袖T恤");
System.out.println("- 短裤/裙子");
System.out.println("- 遮阳帽");
break;
case AUTUMN:
System.out.println("- 长袖衬衫");
System.out.println("- 薄毛衣");
System.out.println("- 牛仔裤");
break;
case WINTER:
System.out.println("- 羽绒服/大衣");
System.out.println("- 毛衣");
System.out.println("- 保暖裤");
System.out.println("- 围巾手套");
break;
}
// 判断是否是夏季或冬季
boolean isExtremeWeather = (currentSeason == Season.SUMMER || currentSeason == Season.WINTER);
System.out.println("\n是否是极端季节(夏季或冬季):" + isExtremeWeather);
}
}
6.2 带有属性和方法的枚举
枚举类型可以包含属性、构造函数和方法,使其更加强大。
生活例子:交通灯系统
public class TrafficLightSystem {
// 定义带有属性和方法的交通灯枚举
enum TrafficLight {
RED(30, "停止"), // 红灯30秒
YELLOW(5, "准备"), // 黄灯5秒
GREEN(45, "通行"); // 绿灯45秒
private final int seconds; // 持续时间(秒)
private final String action; // 对应动作
// 构造函数
TrafficLight(int seconds, String action) {
this.seconds = seconds;
this.action = action;
}
// 获取持续时间
public int getSeconds() {
return seconds;
}
// 获取对应动作
public String getAction() {
return action;
}
}
public static void main(String[] args) {
// 模拟交通灯循环
System.out.println("交通灯系统启动:\n");
for (TrafficLight light : TrafficLight.values()) {
System.out.println(light + "灯亮起...");
System.out.println("持续时间:" + light.getSeconds() + "秒");
System.out.println("行人和车辆动作:" + light.getAction());
System.out.println();
}
// 获取特定交通灯信息
TrafficLight currentLight = TrafficLight.RED;
System.out.println("当前是" + currentLight + "灯");
System.out.println("还需等待" + currentLight.getSeconds() + "秒");
// 使用ordinal()方法获取枚举常量的序号
System.out.println("\n交通灯顺序:");
for (TrafficLight light : TrafficLight.values()) {
System.out.println(light + "的序号是:" + light.ordinal());
}
}
}
7. 控制流程(break, continue, return)
控制流程语句允许我们改变程序的执行顺序,跳出循环或提前结束方法。
7.1 break语句
break语句用于跳出循环或switch语句。
生活例子:找钥匙
public class FindKeys {
public static void main(String[] args) {
String[] places = {"沙发缝隙", "茶几下", "书桌上", "床头柜", "衣服口袋", "鞋柜上"};
String keyLocation = "衣服口袋"; // 钥匙的实际位置
System.out.println("开始寻找钥匙...");
boolean found = false;
for (int i = 0; i < places.length; i++) {
System.out.println("查找位置:" + places[i]);
// 如果找到钥匙,跳出循环
if (places[i].equals(keyLocation)) {
System.out.println("找到钥匙了!在" + places[i]);
found = true;
break; // 找到后立即跳出循环,不再继续查找
}
}
if (found) {
System.out.println("太好了,现在可以出门了。");
} else {
System.out.println("没找到钥匙,可能放在其他地方了。");
}
}
}
7.2 continue语句
continue语句用于跳过当前循环的剩余部分,直接进入下一次循环。
生活例子:购物清单筛选
public class ShoppingListFilter {
public static void main(String[] args) {
// 购物清单:商品名和价格(元)
String[] items = {"苹果", "牛奶", "面包", "巧克力", "牙刷", "矿泉水", "书"};
double[] prices = {10.5, 8.5, 7.5, 20.0, 5.5, 2.0, 45.0};
double budget = 50.0; // 预算
System.out.println("购物预算:" + budget + "元");
System.out.println("\n在预算内可以购买的商品:");
double totalCost = 0.0;
for (int i = 0; i < items.length; i++) {
// 如果当前商品加上已购商品的总价超出预算,跳过该商品
if (totalCost + prices[i] > budget) {
System.out.println(items[i] + "(" + prices[i] + "元) - 超出预算,跳过");
continue; // 跳过当前商品,继续检查下一个
}
// 将商品添加到购物车
totalCost += prices[i];
System.out.println(items[i] + "(" + prices[i] + "元) - 已添加到购物车");
}
System.out.println("\n购物总花费:" + totalCost + "元");
System.out.println("剩余预算:" + (budget - totalCost) + "元");
}
}
7.3 return语句
return语句用于从方法中返回值或结束方法的执行。
生活例子:折扣计算器
public class DiscountCalculator {
public static void main(String[] args) {
double originalPrice = 1200.0; // 原价
int memberLevel = 2; // 会员等级(1-3)
boolean isHoliday = true; // 是否为节假日
// 计算折扣价格
double finalPrice = calculateDiscount(originalPrice, memberLevel, isHoliday);
System.out.println("商品原价:" + originalPrice + "元");
System.out.println("会员等级:" + memberLevel);
System.out.println("是否节假日:" + (isHoliday ? "是" : "否"));
System.out.println("最终价格:" + finalPrice + "元");
}
// 计算折扣价格的方法
public static double calculateDiscount(double price, int level, boolean holiday) {
// 节假日不享受会员折扣
if (holiday) {
System.out.println("节假日不享受会员折扣,但可享受节日9折优惠。");
return price * 0.9; // 返回节假日折扣价
}
// 根据会员等级计算折扣
System.out.println("非节假日,享受会员折扣:");
switch (level) {
case 3: // VIP会员
System.out.println("VIP会员享受7折优惠。");
return price * 0.7; // 返回VIP折扣价
case 2: // 金牌会员
System.out.println("金牌会员享受8折优惠。");
return price * 0.8; // 返回金牌折扣价
case 1: // 普通会员
System.out.println("普通会员享受9折优惠。");
return price * 0.9; // 返回普通折扣价
default: // 非会员
System.out.println("非会员不享受折扣。");
return price; // 返回原价
}