【问题标题】:How to filter records from CSV and add new records to CSV file based on User input in JAVA如何根据 JAVA 中的用户输入从 CSV 过滤记录并将新记录添加到 CSV 文件
【发布时间】:2021-06-13 05:17:50
【问题描述】:

我正在学习 JAVA 并编写一个基本程序,并试图找出一种方法来过滤我的 CSV 中的现有记录,并根据用户输入将新记录添加到我的 CSV 文件中。当用户输入所需的输入时,我正在检查用户输入是否与 CSV 文件中的记录匹配。我想显示相关输入的所有匹配记录。我有不同的方法来完成这项工作。我还创建了一个单独的方法,该方法应将输入的任何新记录添加到 CSV 文件中。为此,我在下面做-

import java.util.Scanner;

public class FilterAndAddEmployeeData {

   ArrayList<Employee>employeeList; // Employeee class is a POJO here

       Scanner userInput = new Scanner(System.in);
       File file = new File("data.csv");
       Employee emp = new Employee(); // This will expect parameters similar to POJO I believe

   public void findByName(String fName, String lName) {
         
          File file = new File(data.csv);
          Scanner x = null;
          System.out.println("Enter first name:")
          String fName = x.next();
          System.out.println("Enter last name:")
          String lName = x.next();
          while(x.hasNextLine()) {
            String fileData = x.next();
            String inputStream = fileData.split(',');
            for(String i: inputStream){
             System.out.println(i); // This will print all 5 rows of my CSV
            }
           }
         }


    public void findById(String id) {
     // TO - DO
    }
    
    public void addEmployee(Employee emp){
     employeeList.add(emp); // To add employee details inputted by user in the employee object
    }
}

这里,我的 Employee 类是一个单独的类,它只有 getter 和 setter 以及成员数据。我在 main() 中调用了这三个单独的方法。 我可以在没有逗号的情况下打印我的 CSV 文件。问题是我无法根据用户输入从 CSV 过滤记录。例如,如果我输入 first name 和 last name ,控制台应该从我的 CSV 打印相应的记录,否则返回 null。有人可以帮我理解这一点吗?我的 CSV 文件有 5 行,其中包含名字、姓氏、年龄、员工 ID 字段。

编辑(根据以下建议):

public void findByName(String fName, String lName) {
Scanner userInput = new Scanner(System.in);
File file = new File("data.csv");


try {
    fileScanner = new Scanner(file);
    fileData = userInput.nextLine();
    System.out.print("Enter first name: --> ");
    String fName = userInput.nextLine().trim();
    System.out.print("Enter last name: --> ");
    String lName = userInput.nextLine().trim();
  //  List<String> foundRecords = new ArrayList<>();
    boolean found = false;
    while (fileScanner.hasNextLine()) {
        fileData = userInput.nextLine().trim();
        // Skip blank lines (if any).
        if (fileData.isEmpty()) {
            continue;
        }

/* The 'Regular Expression' (regex) to use in the String#split() method.
   This will handle any spacing around the comma delimiter when splitting.
   This eliminate the need to carry out array element trimming of leading
   or trailing whitespaces.                                            */
        String regex = "\\s*,\\s*";
        String[] lineParts = fileData.split(regex);
/* Based on the header line information we know that First Name
   data is going to be in column index 0 and the Last Name data
   is going to be in column index 1.                  */
        found = (fName.isEmpty() && lName.isEmpty()) ||
                (lineParts[0].equalsIgnoreCase(fName) && lName.isEmpty()) ||
                (fName.isEmpty() && lineParts[1].equalsIgnoreCase(lName)) ||
                (lineParts[0].equalsIgnoreCase(fName) && lineParts[1].equalsIgnoreCase(lName));
Employee emp = new Employee(lineParts[0],lineParts[1], lineParts[2])
        if (found) {
            employeeList.add(emp);
            found = false;
        }
    }

    // Display found records (if any)
    System.out.println();
    System.out.println("Found Records:");
    System.out.println("====================================");
    if (employeeList.isEmpty()) {
        System.out.println("         No Records Found!");
    }
    else {
        for (Employee str : employeeList) {
            System.out.println(str);
        }
    }
    System.out.println("====================================");

} catch (FileNotFoundException e) {
    e.printStackTrace();
}

}

【问题讨论】:

  • 这是真正的代码sn-p吗?您的 file 似乎没有使用它。

标签: java file-io


【解决方案1】:

这里有一个例子,说明这种事情可能会完成(阅读代码中的 cmets)。它真的没有那么多代码,它只是有很多可以删除的cmets。这只是一个简单的演示:

Scanner userInput = new Scanner(System.in);
File file = new File("data.csv");
String fileData = "";
try (Scanner reader = new Scanner(file)) {
    // Read the header line so we don't deal with it again
    fileData = reader.nextLine();
        
    /* Prompt User for input. 
       - If nothing is entered for either the first name and the
         last name then all records are to be considered 'found'.
        
       - If nothing is provided for the first name and a last name
         is provided then all records containig that last name are
         considered as 'found'.
        
       - If the first name is provided but the last name is not 
         provided then all records containing that first name are
         considered as 'found'.
        
       - If the first name is provided and the last name is provided
         then all records containing that first name and that last 
         name are considered as 'found'.                        */
    System.out.print("Enter first name: --> ");
    String fName = userInput.nextLine().trim();
    System.out.print("Enter last name: --> ");
    String lName = userInput.nextLine().trim();
        
    /* Use an ArrayList or List Interface object to hold any 
       found records. Use this because a List can grow dynamically  */
    List<String> foundRecords = new ArrayList<>(); 
    boolean found = false;
    while (reader.hasNextLine()) {
        fileData = reader.nextLine().trim();
        // Skip blank lines (if any).
        if (fileData.isEmpty()) {
            continue;
        }
            
        /* The 'Regular Expression' (regex) to use in the String#split() method.
           This will handle any spacing around the comma delimiter when splitting.
           This eliminate the need to carry out array element trimming of leading 
           or trailing whitespaces.                                            */
        String regex = "\\s*,\\s*";
        String[] lineParts = fileData.split(regex);
        /* Based on the header line information we know that First Name 
           data is going to be in column index 0 and the Last Name data 
           is going to be in column index 1.                  */
        found = (fName.isEmpty() && lName.isEmpty()) ||
                (lineParts[0].equalsIgnoreCase(fName) && lName.isEmpty()) ||
                (fName.isEmpty() && lineParts[1].equalsIgnoreCase(lName)) || 
                (lineParts[0].equalsIgnoreCase(fName) && lineParts[1].equalsIgnoreCase(lName));
        if (found) {
            foundRecords.add(fileData);
            found = false;
        }
    }
        
    // Display found records (if any)
    System.out.println(); 
    System.out.println("Found Records:");
    System.out.println("====================================");
    if (foundRecords.isEmpty()) {
        System.out.println("         No Records Found!"); 
    }
    else {
        for (String str : foundRecords) {
            System.out.println(str); 
        }
    }
    System.out.println("====================================");
}
catch (FileNotFoundException ex) {
    Logger.getLogger("Method Has An Error!").log(Level.SEVERE, null, ex);
}

如果我使用以下数据创建一个名为 data.csv 的文本文件(文件 是否 有一个标题行 - 代码总是假设有一个):

First Name, Last Name, Age, Employee ID
Jack,       Flash,     32,  10000
Bob,        Smith,     27,  10008
Willy,      Wonka,     54,  11023
Sam,        Smith,     82,  13001
Betty,      Boop,      55,  10044 

然后在控制台窗口中输入:

Enter first name: --> 
Enter last name: --> smith

控制台窗口将显示:

Found Records:
====================================
Bob,        Smith,     27, 10008
Sam,        Smith,     82, 13001
====================================

【讨论】:

  • 我看到你在 try--Scanner reader = new Scanner(file) 中传递参数。那很重要吗?我可以不只是在我的 try 块中添加那行吗?
  • 我已经通过放入三种不同的方法更新了我的代码——我的第一个方法负责按名称搜索记录。第二种方法是通过 id 搜索记录。第三种方法应将用户输入(名字、姓氏和 id)添加到 Employee 类。如果您的 ArrayList 不是 String 并且类型为 EMployee(它本身就是一个类),您该怎么做。
  • @techie_questie - 关于 try 块:是的,您可以,只要确保在完成阅读器以释放资源后关闭阅读器即可。上面的 try 块称为Try With Resources 块。完成后它将自动关闭扫描仪阅读器。
  • 这是一个完全不同的问题,应该单独发布。您的 Employee 类应该有一个构造函数,该构造函数将在 Employee 类被实例化时接受构成 Employee 实例所需的参数,例如:public Employee (String firstName, String lastName, int age, int idNumber) { this.firstName = firstName; this.lastName = lastName; this.age = age; this.idNumber = idNumber; }。现在,当从另一个类中使用时:Employee empl = new Employee("Jack", "Flash", 23, 43344); 创建和 Employee 的另一个实例。
  • 如果您发现此答案有帮助,请标记它。
【解决方案2】:

split 有这个签名public String[] split(String regex)。因此,您可以像 String name = inputStream[3] 一样对 String[] 进行索引以检索一些值。然后你可以应用条件逻辑,如:

if ( name.equals(firstName)) {
    System.out.println("output");
}

当心输入错误,例如嵌入在列值中的逗号。

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多