0

I am a newbie of c++. Now I am doing a project need to read a customer list from a csv file and then search if there is a username like "Ali" and printout all the data about Ali. How can I search "Ali" and printout all the data about Ali like CustomerNo , Name , PhoneNo and Status? And if there is multiple data with "Ali" , how can I printout all of them either? Here is my code:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Iterator;

public class LoadCustomer {
    public static void main(String[] args) throws IOException{
        System.out.println ("Load customer from file");
        ArrayList<Customer> customers = readCustomerFromFile();
    
        System.out.println (customers);
        System.out.println ();

    
    private static ArrayList<Customer> readCustomerFromFile() throws IOException{
        ArrayList<Customer> customers = new ArrayList<>();
        List<String> lines = Files.readAllLines(Paths.get("customer.csv"));
        for (int i = 1 ; i < lines.size() ; i++){
            String[] items = lines.get(i).split(",");
            int customerNo = Integer.parseInt(items[0]);
            int phoneNo = Integer.parseInt(items[2]);
            customers.add (new Customer(customerNo,items[1],phoneNo,items[3]));
        }
        return customers;
    }
}

Here is my Customer class:(added getName getter)

public class Customer {
private int customerNo;
private String name;
private int phoneNo;
private String status;
public Customer () {}
public Customer (int customerNo, String name, int phoneNo, String status){
    this.customerNo = customerNo;
    this.name = name;
    this.phoneNo = phoneNo;
    this.status = status;
}
public String getName(){
    return name;
}

public String toString(){
    return customerNo + " " + name + " " + phoneNo + " " + status;
}
public String toCSVString(){
    return customerNo + "," + name + "," + phoneNo + "," + status;
}
}

And here is my data:

 CustomerNo            Name       PhoneNo     Status
    1                  Ali        12345        Normal
    2                  Siti       23456        Normal
    3                  Rone       78910        Normal
    4                  Jean       56789        Normal
    5                  Roby       28573        Normal
    6                  Ali        78532        Normal

Thank you very much for your attention. Edited : Here is my code for this program:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;


public class FindCustomer {
    public static void main(String[] args) throws IOException{
        System.out.println ("Load customer from file");
        java.util.Map<String, List<Customer>> customers =
        Files.lines(Paths.get("customer.csv"))
                .map(line -> line.split(","))
                .map(field -> new Customer(
                        Integer.parseInt(field[0]), field[1],
                        Integer.parseInt(field[2]), field[3]))
                .collect(Collectors
                        .groupingBy(Customer::getName));
        System.out.println (customers);
    }

}

1
  • 1
    How would you have done it in C++? Commented Jan 5, 2021 at 16:04

2 Answers 2

1

Bit of a broad question.

If you expect to do this a lot, and on a boatload of data, do what everybody else does when they are faced with a lot of relational data that they need to run queries on. Use a database, like postgres or h2. To interact with those from java, use JDBI or JOOQ.

If this is just a small simple text file and/or you're trying to learn some java, well, you still have two options here: You can loop through the data, or, you can build a mapping.

The loop option is simple:

for (Customer c : customers) if (c.getName().equals("Ali")) {
   // do what you want here. 'c' holds the customer object of Ali.
}

But this does, of course, require a full run through all the entries every time. Another option is to build a mapping:

var map = new HashMap<String, Customer>();
for (Customer c : customers) map.put(c.getName(), c);
// map now maps a customer name to the customer object.
Customer ali = map.get("Ali");

maps have the advantage that they are near instant lookup. Even if the map contains a million entries, map.get(x) is (near) instant. A decent solution if you have lots of data + the need to do lots of lookups. But, you have to build a complete map for everything you care to query on. So, if you want to do lookups on name, and then later something like 'get all customers with a 6 digit phone number whose status is Normal', then, get a database.

Sign up to request clarification or add additional context in comments.

1 Comment

Ali exists twice so the last statement won't work or will only return the most recent addition. Probably needs a HashMap<String, List<Customer>>
0

As was suggested a map would be useful. You can create one on the fly as you read in the file.

  • Splits the line
  • creates a customer.
  • and groups it by name in a map.

Now the map will hold for each name, all customers that have that name.

Map<String, List<Customer>> customers =
        Files.lines(Paths.get("customer.csv"))
                .map(line -> line.split("\\s*,\\s*"))
                .map(field -> new Customer(
                        Integer.parseInt(field[0]), field[1],
                        Integer.parseInt(field[2]), field[3]))
                .collect(Collectors
                        .groupingBy(Customer::getName));


To get the List of customers for the name Ali do the following.

List<Customer> ali = customers.get("Ali");

Now it's up to you to format or otherwise use the list as required. You will still need to handle exceptions via try/catch.

10 Comments

I get an error of "The method groupingBy(Function<? super T,? extends K>) in the type Collectors is not applicable for the arguments (Customer::getName)" and "The type Customer does not define getName(T) that is applicable here" , what is going on?
Does your Customer class have a getName getter that returns a String? You didn't show your class so I had to make an assumption.
Edited Customer class.
Did you get it to work? If not I will check it out. It just worked fine for me using your class.
Not , I meet a lot of error message when running the code, such as: Exception in thread "main" java.lang.NumberFormatException: For input string: "12345" , at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.base/java.lang.Integer.parseInt(Integer.java:638) at java.base/java.lang.Integer.parseInt(Integer.java:770)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.