203 lines
6.9 KiB
Java
203 lines
6.9 KiB
Java
package chapter5;
|
||
|
||
/**
|
||
* 双十一购物车
|
||
* 需求:
|
||
* 1. 添加商品到购物车(商品名称用StringBuilder拼接)
|
||
* 2. 显示购物车商品清单(把StringBuilder转换为String输出)
|
||
* 3. 修改商品名称(用String的replace方法)
|
||
* 4. 删除购物车某个商品(用StringBuilder的delete方法)
|
||
* 5. 计算购物车商品总价
|
||
*/
|
||
public class ShoppingCart {
|
||
private StringBuilder cart; // 购物车商品列表
|
||
private double totalPrice; // 总价格
|
||
|
||
/**
|
||
* 构造方法思路:
|
||
* 1. 创建空的购物车,使用StringBuilder存储商品信息
|
||
* 2. 初始化总价为0
|
||
* 为什么使用StringBuilder?因为购物车内容会经常变动,StringBuilder更适合频繁修改
|
||
*/
|
||
public ShoppingCart() {
|
||
cart = new StringBuilder();
|
||
totalPrice = 0.0;
|
||
}
|
||
|
||
/**
|
||
* addItem方法思路:
|
||
* 1. 判断购物车是否为空
|
||
* - 如果不空,需要先添加分隔符", "
|
||
* - 如果是空的,直接添加商品
|
||
* 2. 拼接商品信息:商品名(¥价格)
|
||
* 例如:小米手机(¥1999.0)
|
||
* 3. 更新总价
|
||
*
|
||
* 考虑:为什么要加if判断?
|
||
* - 为了避免第一个商品前也加逗号
|
||
* - 让商品列表更美观:商品1(¥xx), 商品2(¥xx), 商品3(¥xx)
|
||
*/
|
||
public void addItem(String item, double price) {
|
||
if (!cart.isEmpty()) {
|
||
cart.append(", ");
|
||
}
|
||
cart.append(item).append("(¥").append(price).append(")");
|
||
totalPrice += price;
|
||
}
|
||
|
||
/**
|
||
* showCart方法思路:
|
||
* 1. 先判断购物车是否为空
|
||
* - 如果为空,返回提示信息
|
||
* - 如果不为空,显示商品清单和总价
|
||
* 2. 把StringBuilder转换为String返回
|
||
*
|
||
* 为什么要转换成String?
|
||
* - String更适合显示最终结果
|
||
* - println方法接收String类型参数
|
||
*/
|
||
public String showCart() {
|
||
if (cart.isEmpty()) {
|
||
return "购物车是空的呢,快去选购吧!";
|
||
}
|
||
return "购物车商品: " + cart.toString() + "\n总价: ¥" + totalPrice;
|
||
}
|
||
|
||
/**
|
||
* modifyItem方法思路:
|
||
* 1. 先将StringBuilder转换为String
|
||
* 2. 使用String的replace方法替换商品名
|
||
* 3. 将修改后的String再转回StringBuilder
|
||
*
|
||
* 为什么要转换来转换去?
|
||
* - String的replace方法使用更方便
|
||
* - StringBuilder没有直接的替换方法
|
||
* 注意:这里没有修改价格,实际项目中可能需要考虑价格变化
|
||
*/
|
||
public void modifyItem(String oldItem, String newItem) {
|
||
String cartStr = cart.toString();
|
||
cartStr = cartStr.replace(oldItem, newItem);
|
||
cart = new StringBuilder(cartStr);
|
||
}
|
||
|
||
/**
|
||
* removeItem方法思路:
|
||
* 1. 找到要删除商品名的起始位置(indexOf)
|
||
* 2. 如果找到了(start != -1):
|
||
* - 找到这个商品信息的结束位置(")"的位置再+1)
|
||
* - 如果后面还有商品,则多删除", "这两个字符
|
||
* 3. 使用StringBuilder的delete方法删除
|
||
* 4. 更新总价
|
||
*
|
||
* 难点解析:
|
||
* end < cart.length() && cart.charAt(end) == ','
|
||
* - 为什么要判断end < cart.length()?避免数组越界
|
||
* - 为什么要判断逗号?确保后面还有其他商品
|
||
*/
|
||
public void removeItem(String item, double price) {
|
||
int start = cart.indexOf(item);
|
||
if (start != -1) {
|
||
int end = cart.indexOf(")", start) + 1;
|
||
if (end < cart.length() && cart.charAt(end) == ',') {
|
||
end += 2; // 删除后面的逗号和空格
|
||
}
|
||
cart.delete(start, end);
|
||
totalPrice -= price;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清空购物车方法思路:
|
||
* 1. 使用StringBuilder的setLength(0)清空购物车内容
|
||
* - 比创建新对象更高效
|
||
* - 比delete(0,length)更简洁
|
||
* 2. 重置总价为0
|
||
*
|
||
* 为什么用setLength(0)而不是cart = new StringBuilder()?
|
||
* - setLength(0)只是将长度设为0,原有空间仍可重用
|
||
* - 创建新对象会产生额外的内存开销
|
||
*/
|
||
public void clearCart() {
|
||
cart = new StringBuilder();
|
||
totalPrice = 0.0;
|
||
}
|
||
|
||
/**
|
||
* 对购物车中指定商品应用折扣
|
||
* 折扣范围: 0.0-1.0 (例如0.8表示8折)
|
||
* 实现思路:
|
||
* 1. 检查折扣是否合法
|
||
* 2. 在购物车中查找商品
|
||
* 3. 提取商品原价
|
||
* 4. 计算新价格并更新购物车
|
||
* 5. 更新总价
|
||
*
|
||
* @param item 要打折的商品名称
|
||
* @param discount 折扣率(0.0-1.0)
|
||
* @throws IllegalArgumentException 当折扣不在有效范围内时抛出
|
||
*/
|
||
public void applyDiscount(String item, double discount) {
|
||
// 验证折扣是否合法
|
||
if (discount <= 0.0 || discount >= 1.0) {
|
||
throw new IllegalArgumentException("折扣必须在0.0到1.0之间");
|
||
}
|
||
|
||
// 查找商品在购物车中的位置
|
||
String cartStr = cart.toString();
|
||
int itemStart = cartStr.indexOf(item);
|
||
if (itemStart == -1) {
|
||
return; // 商品不存在,直接返回
|
||
}
|
||
|
||
// 提取价格信息
|
||
int priceStart = cartStr.indexOf("¥", itemStart);
|
||
int priceEnd = cartStr.indexOf(")", priceStart);
|
||
double originalPrice = Double.parseDouble(cartStr.substring(priceStart + 1, priceEnd));
|
||
|
||
// 计算新价格
|
||
double newPrice = originalPrice * discount;
|
||
|
||
// 更新总价
|
||
totalPrice = totalPrice - originalPrice + newPrice;
|
||
|
||
// 更新购物车中的价格
|
||
String oldPriceStr = String.format("¥%.1f", originalPrice);
|
||
String newPriceStr = String.format("¥%.1f", newPrice);
|
||
cart.replace(priceStart, priceEnd, newPriceStr);
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
// 测试购物车
|
||
ShoppingCart cart = new ShoppingCart();
|
||
System.out.println(cart.showCart());
|
||
System.out.println();
|
||
|
||
// 添加商品
|
||
cart.addItem("小米手机", 1999.0);
|
||
cart.addItem("耳机", 299.0);
|
||
cart.addItem("充电器", 39.9);
|
||
System.out.println("添加商品后:");
|
||
System.out.println(cart.showCart());
|
||
|
||
// 修改商品名称
|
||
cart.modifyItem("小米手机", "华为手机");
|
||
System.out.println("\n修改商品后:");
|
||
System.out.println(cart.showCart());
|
||
|
||
// 应用商品折扣
|
||
cart.applyDiscount("耳机", 0.8);
|
||
System.out.println("\n应用折扣后:");
|
||
System.out.println(cart.showCart());
|
||
|
||
// 删除商品
|
||
cart.removeItem("耳机", 299.0);
|
||
System.out.println("\n删除商品后:");
|
||
System.out.println(cart.showCart());
|
||
|
||
// 清空购物车
|
||
cart.clearCart();
|
||
System.out.println("\n清空购物车后:");
|
||
System.out.println(cart.showCart());
|
||
}
|
||
}
|