
本文详细介绍了在java中使用`arraylist
在Java应用程序开发中,尤其是在处理库存或订单系统时,经常需要管理包含多个字段的列表数据。一个常见的场景是,我们有一个产品ID和其对应数量的组合,并希望将这些组合存储在一个动态列表中。当用户添加新的订单项时,如果该产品ID已经存在于列表中,我们应该更新其数量,而不是简单地添加一个重复的条目。本文将详细探讨如何使用ArrayList<int[]>来有效地实现这一逻辑,并避免常见的陷阱。
假设我们有一个ArrayList<int[]>,其中每个int[]代表一个订单项,int[0]存储产品ID,int[1]存储产品数量。当用户输入一个新的产品ID (idConso) 和数量 (nbrConso) 时,我们需要检查ArrayList中是否已存在该idConso。如果存在,则将现有条目的数量增加nbrConso;否则,添加一个新的订单项。
初学者在实现此功能时,常犯的错误包括:
不正确的contains方法使用: 尝试使用ord.contains(Order[0] == idConso)这样的表达式来检查。
立即学习“Java免费学习笔记(深入)”;
数组对象引用问题: 在循环外部声明并初始化int[] Order = new int[2];。
为了正确地实现订单项的检查和更新,我们需要手动遍历ArrayList,比较每个int[]元素的第一个索引(产品ID),并根据结果执行相应的操作。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class OrderManager {
// 假设 NAMES 数组和其他辅助方法已定义
final static String NAMES[] = {
"Spa reine 25 ","Bru plate 50","Bru pét 50","Pepsi","Spa orange",
"Schweppes Tonic","Schweppes Agr","Ice Tea","Ice Tea Pêche","Jus d'orange Looza", "Cécémel",
"Red Bull","Petit Expresso","Grand Expresso","Café décaféiné ","Lait Russe ","Thé et infusions",
"Irish Coffee ","French Coffee ","Cappuccino","Cécémel chaud","Passione Italiano","Amour Intense",
"Rhumba Caliente ","Irish Kisses ","Cuvée Trolls 25","Cuvee Trolls 50","Ambrasse-Temps 25","Ambrasse-Temps 50 ",
"Brasse-Temps Cerises 25","Brasse-Temps Cerises 50","La Blanche Ste Waudru 25","Blanche Ste Waudru 50",
"Brasse-Temps citr 25","Brasse-Temps citr 50","Spaghetti Bolo ","Tagl Carbonara","Penne poulet baslc ",
"Tagl American","Tagl saum"
};
public static String getUserIntOrSpecificInputV2(String msg, String expectedAnsw, int min, int max) {
int intInput = 0;
String strAnsw = "";
Scanner sc = new Scanner(System.in);
do {
System.out.println(msg);
if (sc.hasNextInt()) {
intInput = sc.nextInt();
if (intInput >= min && intInput <= max) {
return Integer.toString(intInput);
} else {
System.out.println("La saisie doit être comprise entre " + min + " et " + max);
}
} else {
strAnsw = sc.next();
if (strAnsw.length() == 1 && expectedAnsw.toUpperCase().contains(strAnsw.toUpperCase())) {
return strAnsw.toUpperCase();
} else {
System.out.println("Erreur de saisie : caractères autorisés " + expectedAnsw);
}
}
} while (true);
}
public static void getOrder(ArrayList<int[]> ord) {
String UserInput;
int idConso = 0, nbrConso = 0;
do {
UserInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) ", "Q", 1, NAMES.length);
if (UserInput.equalsIgnoreCase("Q")) {
System.out.println("Fin de Programme, Au Revoir");
System.exit(-1);
} else {
idConso = Integer.parseInt(UserInput);
}
UserInput = getUserIntOrSpecificInputV2("Nombre de consommations pour " + NAMES[idConso - 1] + " ? /A(Annuler) /Q (Quitter)", "AQ", 1, 5000);
if (UserInput.equalsIgnoreCase("Q")) {
System.out.println("Fin de Programme, Au Revoir");
System.exit(-1);
} else if (UserInput.equalsIgnoreCase("A")) {
// 用户选择取消,跳过本次订单项处理,重新输入产品ID
continue;
}
nbrConso = Integer.parseInt(UserInput);
// 标志位,用于判断是否找到并更新了现有订单项
boolean foundAndUpdated = false;
// 遍历现有订单列表,检查产品ID是否已存在
for (int[] existingOrder : ord) {
if (existingOrder[0] == idConso) {
// 找到匹配的产品ID,更新数量
System.out.println("产品ID " + idConso + " 已存在,更新数量。");
existingOrder[1] += nbrConso;
foundAndUpdated = true; // 设置标志位
break; // 找到并更新后,即可退出循环
}
}
// 如果没有找到匹配的产品ID,则添加新的订单项
if (!foundAndUpdated) {
// 关键点:每次添加新订单项时,都创建一个新的 int[] 对象
int[] newOrder = new int[2];
newOrder[0] = idConso;
newOrder[1] = nbrConso;
ord.add(newOrder);
System.out.println("添加新订单项: " + Arrays.toString(newOrder));
}
// 询问下一个操作
UserInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) V (Valider le ticket) ", "QV", 1, NAMES.length);
} while (!UserInput.equalsIgnoreCase("V"));
System.out.println("\n--- 最终订单列表 ---");
for (int[] item : ord) {
System.out.println(NAMES[item[0] - 1] + ": " + item[1] + " 份 (ID: " + item[0] + ")");
}
System.out.println("订单总项数: " + ord.size());
}
public static void main(String[] args) {
ArrayList<int[]> orderList = new ArrayList<>();
getOrder(orderList);
}
}迭代查找 (for 循环):
boolean foundAndUpdated = false;
for (int[] existingOrder : ord) {
if (existingOrder[0] == idConso) {
existingOrder[1] += nbrConso;
foundAndUpdated = true;
break;
}
}正确实例化数组对象 (new int[2]):
if (!foundAndUpdated) {
int[] newOrder = new int[2]; // 每次添加新项时,都创建一个新的 int[] 对象
newOrder[0] = idConso;
newOrder[1] = nbrConso;
ord.add(newOrder);
}用户输入处理 (continue): 在getOrder方法中,如果用户输入'A'(Annuler),表示取消当前订单项的输入,我们使用continue语句跳过当前循环的剩余部分,直接进入下一次循环,重新提示用户输入产品编号。
尽管ArrayList<int[]>可以工作,但在实际项目中,通常推荐使用自定义类来表示订单项,因为这样能提供更好的可读性、可维护性和扩展性。
示例:使用自定义类 OrderItem
// 定义一个自定义类来表示订单项
class OrderItem {
private int productId;
private int quantity;
public OrderItem(int productId, int quantity) {
this.productId = productId;
this.quantity = quantity;
}
public int getProductId() {
return productId;
}
public int getQuantity() {
return quantity;
}
public void addQuantity(int amount) {
this.quantity += amount;
}
// 重写 equals 和 hashCode 方法,以便 ArrayList.contains() 和 Map 可以正确比较对象
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderItem orderItem = (OrderItem) o;
return productId == orderItem.productId; // 只根据 productId 判断是否相等
}
@Override
public int hashCode() {
return Integer.hashCode(productId); // 只根据 productId 生成哈希码
}
@Override
public String toString() {
return "OrderItem{" +
"productId=" + productId +
", quantity=" + quantity +
'}';
}
}使用自定义类后,getOrder方法中的逻辑可以这样调整:
// ... 在 getOrder 方法中 ...
// 在循环内部获取 idConso 和 nbrConso 后
OrderItem newOrderItem = new OrderItem(idConso, nbrConso);
boolean foundAndUpdated = false;
for (OrderItem existingItem : ord) { // 假设 ord 现在是 ArrayList<OrderItem>
if (existingItem.equals(newOrderItem)) { // 使用重写的 equals 方法比较
existingItem.addQuantity(nbrConso);
foundAndUpdated = true;
break;
}
}
if (!foundAndUpdated) {
ord.add(newOrderItem);
}
// ...使用 HashMap 进行更高效的查找
如果订单列表非常大,每次都遍历ArrayList会影响性能(O(N))。在这种情况下,可以使用HashMap<Integer, OrderItem>,其中键是产品ID,值是OrderItem对象。这样,查找操作的平均时间复杂度可以达到O(1)。
// 在 main 方法中
// HashMap<产品ID, OrderItem对象>
HashMap<Integer, OrderItem> orderMap = new HashMap<>();
// 在 getOrder 方法中
// ... 获取 idConso 和 nbrConso 后 ...
if (orderMap.containsKey(idConso)) {
// 已存在,更新数量
OrderItem existingItem = orderMap.get(idConso);
existingItem.addQuantity(nbrConso);
System.out.println("产品ID " + idConso + " 已存在,更新数量。");
} else {
// 不存在,添加新项
OrderItem newOrderItem = new OrderItem(idConso, nbrConso);
orderMap.put(idConso, newOrderItem);
System.out.println("添加新订单项: " + newOrderItem);
}
// ... 最终打印时,遍历 orderMap.values() ...在Java中使用ArrayList<int[]>管理具有唯一ID和可变数量的订单数据时,理解并正确处理以下两点至关重要:
对于更复杂的场景或对性能有更高要求时,考虑使用自定义类并重写equals和hashCode方法,或采用HashMap等数据结构,可以显著提升代码的可读性、可维护性和执行效率。
以上就是Java中管理订单列表:高效检查与更新一维数组元素的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号