Reputation: 17
I don't know why my previous question is closed so I decide to ask the question in another way. Hi I am a newbie of Java programming , I have some problem about reading data from a CSV file. Here is my CSV file:
1,Ali,1201345673,Normal
2,Siti,1307891435,Normal
Here is how I read the data:
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));
System.out.println (customers);
return customers;
Customer class:
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;
}
Then I realize that this is how my map look like:
(Ali = ["1 Ali 1201345673 Normal"] , Siti = ["2 Siti 1307891435 Normal"])
But not the way I want like this:
(Ali = [1 , "Ali" , 1201345673 , "Normal" ] , Siti = [2 , "Siti" , 1307891435 , "Normal" ])
In this for Ali , 1 is an element , Ali is an element , 1201345673 is an element and Normal is another element.
The data of every person has been read into an element in my List so I can't not output them like an Array list . So the problem is how can I separate the every element in the list when I read the CSV data and I really need the Map function of the program so please keep it , or maybe how can I read the data as a array list in my map. Thank you for your attention.
Upvotes: 1
Views: 1122
Reputation: 20923
I believe the following achieves what you desire.
/*
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
*/
Supplier<List<List<Object>>> s = () -> new ArrayList<List<Object>>();
BiConsumer<List<List<Object>>, Customer> b = (l, c) -> {
l.add(c.toList());
};
BinaryOperator<List<List<Object>>> o = (l1, l2) -> {l1.addAll(l2); return l1;};
Collector<Customer, List<List<Object>>, List<List<Object>>> c = Collector.of(s, b, o);
Map<String, List<List<Object>>> 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,
Collectors.mapping(Function.identity(), c)));
System.out.println(customers);
The output is
{Siti=[[2, Siti, 1307891435, Normal]], Ali=[[1, Ali, 1201345673, Normal]]}
I created a custom Collector
, i.e. I wrote an implementation of the Collector
interface.
Each value in the Map
, i.e. customers
, is a list of lists. According to your sample CSV file, there are two lines in the file, each with a separate name. Hence the Map
contains two entries and the value for each entry is a list that contains a single element which is itself a list. That's why the output shows double [
and ]
characters.
Note that I added method toList
to class Customer
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 List<Object> toList() {
return List.of(customerNo, name, phoneNo, status);
}
public String toString() {
return customerNo + " " + name + " " + phoneNo + " " + status;
}
}
Upvotes: 0
Reputation: 75
That's because of toString() method. It defines how the class will be printed by basically defining a custom formatted string.
if you change it to as following :
public String toString(){
return customerNo + ", " + name + ", " + phoneNo + ", " + status;
}
It will print as :
Ali = ["1, Ali, 1201345673, Normal"]
You can customize this function to print it the way you want.
try this :
public String toString(){
return customerNo + ", \"" + name + "\", " + phoneNo + ", \"" + status + "\"";
}
Upvotes: 1