java - 如何从文件中读取特定对象的数组列表
问题描述
我正在做一个编程项目,您想为在线购物商店编写代码,我有两个文件,一个包含产品,另一个包含帐户信息,我需要读取这两个文件并将它们存储在 ArrayList和另一个类型为帐户,如下所示在商店类中,我还想检查登录信息是否匹配
我已经尝试将两个文件读取到 list1 和 list2 (它们是 String 类型的数组列表)并且它完全工作正常但是当我到达我想检查用户名和密码是否有效的地步时,我尝试了以下操作:
int accountIndex=-1;
for (int i = 0; i < list2.size(); i++) {
if((list2.get(i).contains(username))&& (list2.get(i).contains(password))){
accountIndex=0;
}
}
if(accountIndex<0)
System.out.println("Login Failed! Invalid Username and/or Password.\n");
但它不适用于所有情况并且存在一些错误,所以我的老师告诉我将文件读入已经存在的产品和帐户数组列表中,但我还没有找到合适的方法......
这是帐户文件包含的示例:
0001,Salam,1234,AbdulSalam Ahmad,1223 Sultanah - Medina,05555343535,salam@hotmail.com
0002,Rawan,1111,Rawan Khaled,1223 Alaziziah - Medina,05555343435,rawan@hotmail.com
//主要的:
public static void main(String[] args) throws FileNotFoundException {
int ans;
// Craete a Store object
Store store = new Store("Camera Online Store");
// Read all products from the products file
ArrayList<String>list1=new ArrayList<String>();
File products = new File("Products.txt");
try(Scanner input = new Scanner(products);)
{
input.useDelimiter(",");
while(input.hasNext()){
list1.add(input.nextLine());
}
input.close();
}
// Read all accounts from the account file
File customerFile = new File("Accounts.txt");
ArrayList<String>list2=new ArrayList<String>();
try(Scanner input = new Scanner(customerFile);)
{
input.useDelimiter(",");
while(input.hasNext()){
list2.add(input.nextLine());
} input.close();
}
System.out.println("^^^^^^ Welcome to our "+store.getName()+" ^^^^^");
System.out.println("*****************************************");
while(true)
{
System.out.println("Are you a customer or an admin?\n (1) for user \n (2) for admin\n (3) to exit");
Scanner sc = new Scanner (System.in);
int choice = sc.nextInt();
switch (choice) {
case 1: // customer mode
System.out.println("Enter your login information.");
System.out.print("Username:");
String username = sc.next();
System.out.print("Password:");
String password = sc.next();
int accountIndex=-1;
for (int i = 0; i < list2.size(); i++) {
if((list2.get(i).contains(username))&& (list2.get(i).contains(password))){
accountIndex=0;
}
}
/*
get the account index for this customer
*/
if(accountIndex<0)
System.out.println("Login Failed! Invalid Username and/or Password.\n");
else{
do
{
System.out.println("Choose the required operations from the list below:\n (1) Display all products \n (2) Add a product to your shopping cart by id \n (3) View the products in your shopping cart \n (4) Go to checkout\n (5) Go back to main menu");
//Store class:
class Store{
private String name;
private ArrayList<Account> arracc;
private ArrayList<Products> arrprod;
public Store(){
}
public void setArrAcc(Account x){
arracc.add(x);
}
public void setArrProd(Products x){
arrprod.add(x);
}
public Store(String name){
this.name=name;
}
public void addProduct(Products p){
arrprod.add(p);
}
public void deleteProduct(int id){
arrprod.remove(id);//id is the product index
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
}
//products class:
class Products{
private int productID;
private String name;
private String supplier;
private double price;
public Products(){
}
public Products(int productID,String name,String supplier, double price){
this.productID=productID;
this.name=name;
this.supplier=supplier;
this.price=price;
}
public void setProductID(int ID){
productID=ID;
}
public void setName(String newName){
name=newName;
}
public void setSupplier(String newSupplier){
supplier=newSupplier;
}
public void setPrice(double newPrice){
price=newPrice;
}
public int getID(){
return productID;
}
public String getSupplier(){
return supplier;
}
public String getNAme(){
return name;
}
public double getPrice(){
return price;
}
public String toString(){
return" Product ID: "+productID+"\n -Product Name: "+name+"\n -Product Supplier: "+supplier+
"\n -Product Price: "+price+"\n ******************************************";
}
}
任何帮助将非常感激!!
解决方案
使用 Scanner 从数据文件中读取文本行时,不要使用Scanner#next()方法,除非您特别想要文件中的每个标记(单词)。当与Scanner#hasNext()方法一起使用时,它专门用于从文件中检索标记(单词) 。将Scanner#hasNextLine()与Scanner#nextLine()方法结合使用。这是一个例子:
File customerFile = new File("Accounts.txt");
ArrayList<String> accountsList = new ArrayList<>();
// Try With Resources...
try (Scanner input = new Scanner(customerFile)) {
while (input.hasNextLine()) {
String line = input.nextLine().trim(); // Trim each line as they are read.
if (line.equals("")) { continue; } // Make sure a data line is not blank.
accountsList.add(line); // Add the data line to Account List
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
您会注意到我没有将 Account List 命名为list2。尽管这是一个偏好问题,但它的描述性还不够。我方便地将其命名为accountsList,这样可以更轻松地查看变量的用途。
尽管您可以侥幸成功,但我不会使用contains()方法检查User Name和Password。当帐户列表变大时,您会发现它不够准确。相反,将每个帐户行拆分为一个字符串数组并访问用户名和密码所在的特定索引,例如:
int accountIndex = -1;
for (int i = 0; i < accountsList.size(); i++) {
// Split the current accounts data line into a String Array
String[] userData = accountsList.get(i).split(",");
// Check User Name/Password valitity.
if (userData[1].equals(username) && userData[2].equals(password)) {
accountIndex = i;
break; // Success - We found it. Stop Looking.
}
}
现在,这当然是假设在每个帐户数据行中,第一项是 ID 号,第二项是用户名,第一项是密码。如果将这一行拆分为一个字符串数组,则第一项(ID)位于数组索引 0,第二项(用户名)位于数组索引 1,第三项(密码)位于数组索引 2 , 等等。
您还有一个名为accountIndex(好名)的变量,但在成功找到用户名和密码后,您向该变量提供0 。通过这样做,您实际上是在告诉您的代码成功的帐户实际上是帐户列表中包含的第一个帐户,而不管用户名和密码是否已通过有效性。您应该传递给此变量的是i中包含的值,如上例所示,因为这是传递用户名/密码有效性的 Accounts List 元素的真实索引值。
您的其余代码尚未提供,因此您可以从这里自行处理。
推荐阅读
- powerbi - 切片器仅显示月/年并对其进行过滤
- csv - 如何在朱莉娅的 CSV 文件中保存代码的输出
- bash - Gradle 输出在 VS Code 的 bash 终端中未正确格式化
- winforms - Windows 窗体子菜单自动隐藏延迟 - 如何保持子菜单短暂打开以获得更宽容的鼠标控制
- java - 如何在 Intellij 的类路径上添加一个类?
- azure-devops - 如何在 Azure Devops 中的审阅者选择之前隐藏大型代码块?
- angular - 笑话:无法设置未定义的属性“”(Angular)
- c# - 如何在我的代码中解决此问题。“参数 1:不能将字符串转换为布尔值”
- python - 使用 Pipenv 和 setup.py 将包发布并安装到 Github
- asp.net - 使用 ASP.NET Web Api 和 Angular 10 进行授权