新闻中心
J*a中管理一维数组列表:检查、更新与新增元素的高效策略

本教程旨在解决在j*a `arraylist
J*a ArrayList中的元素管理:查找、更新与新增
在J*a应用程序开发中,我们经常需要处理集合数据,其中一种常见场景是管理一个包含一维数组的列表,例如 ArrayList
常见误区与问题分析
初学者在处理这类问题时,常会遇到以下几个误区:
-
ArrayList.contains()的误用: 尝试使用ord.contains(Order[0] == idConso)这样的表达式来检查元素是否存在。
- 问题所在: ArrayList.contains()方法在内部使用元素的equals()方法进行比较。对于原始类型数组(int[]),equals()方法默认比较的是两个数组对象的引用地址,而不是它们的内容。因此,ord.contains(Order[0] == idConso)表达式实际上是尝试在列表中查找一个布尔值(true或false),这显然不是我们想要的结果,且通常会返回false。
- 更进一步,Order[0] == idConso本身在Order[0]被赋值为idConso后总是true,所以contains实际上是在查找true这个布尔对象,这与int[]类型的列表元素毫不相关。
-
对象引用的混淆: 在循环外部声明并初始化数组对象(例如 int[] Order = new int[2];),然后在每次迭代中修改并添加到列表中。
- 问题所在: J*a中的数组是对象。当我们将同一个数组对象多次添加到ArrayList中时,列表中存储的不是数组的副本,而是对同一个数组对象的多个引用。这意味着,如果后续修改了这个数组对象(例如Order[1] += nbrConso;),那么列表中所有引用这个对象的元素都会被修改,导致数据不一致。
正确的解决方案:迭代查找与独立对象处理
为了正确地实现根据ID查找、更新或添加元素,我们需要采取迭代的方式,并确保每次添加的都是独立的数组对象。
1. 迭代查找与更新逻辑
核心思想是遍历ArrayList中的每一个int[]元素,检查其第一个索引的值(商品ID)是否与待处理的ID匹配。
Narration Box
Narration Box是一种语音生成服务,用户可以创建画外音、旁白、有声读物、音频页面、播客等
68
查看详情
import j*a.util.ArrayList;
import j*a.util.Arrays;
import j*a.util.Scanner;
public class OrderManager {
// ... (其他辅助方法如 getUserIntOrSpecificInputV2, NAMES 保持不变) ...
public static void getOrder(ArrayList<int[]> ord) {
String userInput;
int idConso = 0;
int nbrConso = 0;
// 首次获取用户输入
userInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable "
+ "ou Q(Quitter) ", "Q", 1, NAMES.length);
do {
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输入
userInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) V (Valider le ticket) ", "QV", 1, NAMES.length);
continue; // 跳过当前循环的剩余部分,直接进入下一次do-while循环
}
nbrConso = Integer.parseInt(userInput);
// 标志位,用于判断是否找到并更新了现有订单
boolean foundAndUpdated = false;
// 遍历现有订单列表,检查商品ID是否存在
for (int[] existingOrder : ord) {
if (existingOrder[0] == idConso) {
// 找到匹配的商品ID,更新其数量
existingOrder[1] += nbrConso;
System.out.println("更新订单: " + NAMES[idConso - 1] + ", 新数量: " + existingOrder[1]);
foundAndUpdated = true;
break; // 找到并更新后,即可退出循环
}
}
// 如果没有找到匹配的商品ID,则添加新订单
if (!foundAndUpdated) {
// 关键点:在每次需要添加新订单时,都创建一个新的 int[] 数组对象
int[] newOrder = new int[2];
newOrder[0] = idConso;
newOrder[1] = nbrConso;
ord.add(newOrder);
System.out.println("添加新订单: " + NAMES[idConso - 1] + ", 数量: " + nbrConso);
}
// 获取下一个操作的用户输入
userInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) V (Valider le ticket) ", "QV", 1, NAMES.length);
} while (!userInput.equalsIgnoreCase("V")); // 当用户输入不是"V"时继续循环
// 打印最终订单列表
System.out.println("\n--- 最终订单详情 ---");
for (int[] item : ord) {
System.out.println(Arrays.toString(item) + " - " + NAMES[item[0] - 1] + " x " + item[1]);
}
System.out.println("总商品种类数: " + ord.size());
}
public static void main(String[] args) {
ArrayList<int[]> orderList = new ArrayList<>();
getOrder(orderList);
}
// 辅助方法(getUserIntOrSpecificInputV2, checkTable, 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 boolean checkTable(int[] table, int numberCheck) {
for (int i = 0; i < table.length; i++) {
if (table[i] == numberCheck) {
return true;
}
}
return false;
}
}2. 关键改进点解释
- 独立的数组对象: 在if (!foundAndUpdated)块内部,我们声明并初始化了一个新的int[] newOrder = new int[2];。这确保了每次添加新订单时,列表中存储的都是一个全新的、独立的数组对象,避免了对象引用混淆的问题。
- 明确的查找逻辑: 使用增强型for循环for (int[] existingOrder : ord)遍历列表,并通过if (existingOrder[0] == idConso)直接比较商品ID。这种方式清晰、准确地实现了基于内容的查找。
- foundAndUpdated标志位: 这个布尔变量用于记录是否找到了匹配的订单并进行了更新。如果循环结束后foundAndUpdated仍为false,则说明该商品ID是首次出现,需要添加为新订单。
- break语句: 在找到并更新匹配订单后,使用break语句可以立即退出循环,提高效率,因为我们不需要再检查列表中的其余元素。
- 移除不必要的代码: 原始代码中Integer[] OrderLine = new Integer[ord.size()]; OrderLine = ord.toArray(OrderLine); 这两行代码没有实际作用,且可能导致类型转换异常,已被移除。
注意事项与最佳实践
对象引用是关键: 在J*a中,理解对象引用和值传递对于正确管理集合至关重要。当向ArrayList添加对象时,实际上是添加了该对象的引用。
-
自定义类优于原始数组: 对于更复杂的实体,建议创建自定义的类(例如ProductOrder),而不是直接使用int[]。自定义类可以包含有意义的字段名(如productId和quantity),提高代码的可读性和可维护性。此外,自定义类可以重写equals()和hashCode()方法,从而使ArrayList.contains()、ArrayList.remove()以及其他基于内容比较的集合操作更加直观和高效。
// 示例:使用自定义ProductOrder类 class ProductOrder { int productId; int quantity; public ProductOrder(int productId, int quantity) { this.productId = productId; this.quantity = quantity; } // 重写equals和hashCode方法以支持基于内容的比较 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ProductOrder that = (ProductOrder) o; return productId == that.productId; // 仅根据productId判断相等 } @Override public int hashCode() { return Objects.hash(productId); } @Override public String toString() { return "ProductOrder{" + "productId=" + productId + ", quantity=" + quantity + '}'; } } // 在getOrder方法中使用: // ArrayList<ProductOrder> ord = new ArrayList<>(); // ... // ProductOrder newProduct = new ProductOrder(idConso, nbrConso); // int index = ord.indexOf(newProduct); // 如果重写了equals,可以直接查找 // if (index != -1) { // ord.get(index).quantity += nbrConso; // } else { // ord.add(newProduct); // } 输入验证与用户体验: 原始代码中的getUserIntOrSpecificInputV2方法是良好的实践,它提供了健壮的用户输入验证。在实际应用中,应始终确保用户输入符合预期,并提供友好的提示。
总结
在J*a中处理ArrayList
以上就是J*a中管理一维数组列表:检查、更新与新增元素的高效策略的详细内容,更多请关注其它相关文章!
# 数据结构
# 宁波互动营销推广机构
# 网上推广营销网站
# 行业网站建设方案公司
# 武汉顶尖seo
# 小雪seo
# 百度关键词seo网站优化软件
# 数字营销智能推广
# 漳州谷歌网站优化推广
# 网站建设是什么工作内容
# 上城区网站推广平台官网
# 第一个
# 都是
# 重写
# word
# 是否存在
# 遍历
# 列表中
# 文档
# 迭代
# 自定义
# red
# java应用程序
# 常见问题
# ai
# app
# go
# java
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
响应式容器内容自动缩放与宽高比维持教程
J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程
单射、满射与双射的关系 一文理清所有逻辑
优化Log4j2控制台输出性能:解决异步日志瓶颈
React Router v6 教程:构建认证保护的私有路由与重定向策略
腾讯视频怎么举报不良内容_腾讯视频内容举报流程与违规信息处理方法
Yandex免登录网页版地址 Yandex搜索引擎官方访问入口
微博网页版主页入口 微博官方网站免登录访问
京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比
汽水音乐网页版使用入口_汽水音乐电脑版播放指南
UE5.7引擎表现爆炸优化无敌!5090跑4K稳定60FPS
圆通快递查询实时追踪 圆通物流包裹状态快速查看
J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案
Win11怎么关闭快速启动_Win11彻底关机设置教程
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
Pandas DataFrame 多条件优先级排序与排名
Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑
win11怎么查看应用耗电情况 Win11电池设置查看应用能耗排行榜【优化】
sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤
c++中的std::launder有什么实际用途_c++对象生命周期与指针优化
怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法
如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】
C++如何解决segmentation fault_C++段错误调试与原因分析
AO3访问入口汇总 AO3网页版同人作品一键直达
Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明
优化 Python 函数中的条件逻辑:解决 if-else 嵌套与参数选择问题
《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
Log4j Console Appender性能瓶颈与高并发优化策略
C++ map遍历方法大全_C++ map迭代器使用总结
在J*aScript中复现SciPy的B样条拟合与求值:关键考量
c++项目目录结构应该如何组织_c++工程化项目结构规范
React Hooks最佳实践:动态组件状态管理的组件化方案
树莓派传感器触发:通过Twilio API发送WhatsApp消息教程
windows10怎么关闭系统提示音_windows10彻底静音设置方法
Python字典中优雅地迭代剩余元素的方法
如何在网页中实现特定地点的随机图片展示
Angular Material 垂直步进器:实现底部到顶部排序的教程
深入理解Promise链:如何在catch后中断then的执行
韩剧圈正版入口页面_韩剧圈官网登录链接
Excel Power Pivot如何处理XML数据源 构建高级数据模型
Django表单验证失败时保留用户输入数据的最佳实践
Animex动漫社网入口地址 Animex动漫社网正版在线入口
服务端验证_j*ascript输入检查
使用 Pandas 高效处理 .dat 文件:字符清理与数据计算
批改网学生版PC登录 批改网官网登录系统入口
Golang如何实现简单的Web表单_Golang表单提交与验证处理方法
J*a编写用户注册与登录功能_掌握字符串与验证逻辑
夸克AO3官网入口_AO3镜像网站2025推荐
uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验


2025-12-01
浏览次数:次
返回列表
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输入
userInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) V (Valider le ticket) ", "QV", 1, NAMES.length);
continue; // 跳过当前循环的剩余部分,直接进入下一次do-while循环
}
nbrConso = Integer.parseInt(userInput);
// 标志位,用于判断是否找到并更新了现有订单
boolean foundAndUpdated = false;
// 遍历现有订单列表,检查商品ID是否存在
for (int[] existingOrder : ord) {
if (existingOrder[0] == idConso) {
// 找到匹配的商品ID,更新其数量
existingOrder[1] += nbrConso;
System.out.println("更新订单: " + NAMES[idConso - 1] + ", 新数量: " + existingOrder[1]);
foundAndUpdated = true;
break; // 找到并更新后,即可退出循环
}
}
// 如果没有找到匹配的商品ID,则添加新订单
if (!foundAndUpdated) {
// 关键点:在每次需要添加新订单时,都创建一个新的 int[] 数组对象
int[] newOrder = new int[2];
newOrder[0] = idConso;
newOrder[1] = nbrConso;
ord.add(newOrder);
System.out.println("添加新订单: " + NAMES[idConso - 1] + ", 数量: " + nbrConso);
}
// 获取下一个操作的用户输入
userInput = getUserIntOrSpecificInputV2("Entrez le N° de consommable ou Q(Quitter) V (Valider le ticket) ", "QV", 1, NAMES.length);
} while (!userInput.equalsIgnoreCase("V")); // 当用户输入不是"V"时继续循环
// 打印最终订单列表
System.out.println("\n--- 最终订单详情 ---");
for (int[] item : ord) {
System.out.println(Arrays.toString(item) + " - " + NAMES[item[0] - 1] + " x " + item[1]);
}
System.out.println("总商品种类数: " + ord.size());
}
public static void main(String[] args) {
ArrayList<int[]> orderList = new ArrayList<>();
getOrder(orderList);
}
// 辅助方法(getUserIntOrSpecificInputV2, checkTable, 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 boolean checkTable(int[] table, int numberCheck) {
for (int i = 0; i < table.length; i++) {
if (table[i] == numberCheck) {
return true;
}
}
return false;
}
}