How to parse the csv to hashmap grouping by column using opencsv - java

I am trying to use hashmap the col1 values to col2 values from a csv file using CSVREADER. But I am unable to find a logic to do so.
I want to do it through reading the CSV through CSVReader, looping the datalines and using arraylist and hashmap key and value(arraylist). I dont want to hardcode it..
I did something till the following. Unable to proceed further. Please help..
CSVReader csvReader = new CSVReader(new FileReader(fileName),',','"',1);
Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();
ArrayList<String> tablenames = new ArrayList<>();
ArrayList<String> colnames = new ArrayList<>();
while((row = csvReader.readNext()) != null) {
tablenames.add(row[0]);
colnames.add(row[1]);
}
input data:
State,City,Country
NJ,Trenton,US
NJ,Newark,US
NC,Cary,US
NC,Charlotte,US
GA,Atlanta,US
I want the data to be in hashmap as following
[<NJ,[Trenton,Newark]>
<NC,[Cary,Charlotte]>
<GA,[Atlanta]>]

You can try below piece of code :
try
{
CSVReader csvReader = new CSVReader(new FileReader(fileName),',','"',1);
Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();
while((row = csvReader.readNext()) != null)
{
// If map contains state already, add the city to the values list
if(tableandcols.containsKey(row[0]))
{
tableandcols.get(row[0]).add(row[1);
}
// if map doesn't have this state as key, insert a key and value
else {
List<String> cities = new ArrayList<>();
cities.add(row[1]);
tableandcols.put(row[0], cities);
}
}
}
catch(Exception e){
// log exception
}
Alternatively, you can also use HeaderColumnNameTranslateMappingStrategy to map column values to java bean. Loop through the java beans list and aggregate cities based on state.

You can simply do it by using java-8 stream approach, use readAll to read complete file in List<String[]>
Reads the entire file into a List with each element being a String[] of tokens. Since the current implementation returns a LinkedList, you are strongly discouraged from using index-based access methods to get at items in the list. Instead, iterate over the list.
If you want to skip first row with headers then use skip(1), and then use Collectors.groupingBy to group the elements based on State
Map<String, List<String>> res = arr.stream().skip(1)
.collect(Collectors.groupingBy(str -> str[0], Collectors.mapping(str -> str[1], Collectors.toList())));
Or simple for loop using map.compute
List<String[]> arr = csvReader.readAll();
Map<String, List<String>> tableandcols = new HashMap<String, List<String>>();
for(String[] array : arr) {
tableandcols.compute(array[0], (key,val)->val==null ? new ArrayList<>() : val).add(array[1]);
}

Related

If condition for Yaml file- Java

I have the Yaml file:
#Define CDN domains
---
CDN:
quality: 200..300
cost: low
Video-type: mp4
and with this Java code, I retrieve sub values of CDN:
// The path of your YAML file.
Yaml yaml = new Yaml();
Map<String, Map<String, String>> values =
(Map<String, Map<String, String>>) yaml
.load(new FileInputStream(new File("/workspace/servlet-yaml/src/test.yaml")));
for (String key : values.keySet()) {
Map<String, String> subValues = values.get(key);
for (String subValueKey : subValues.keySet()) {
System.out.println(values);
}
}
The output is:
{CDN={quality=200..300, cost=low, Video-type=mp4}}
{CDN={quality=200..300, cost=low, Video-type=mp4}}
{CDN={quality=200..300, cost=low, Video-type=mp4}}
First of all, I don't know why it repeats three times?
Secondly, I want to write a code that
if cost = low , then do somthing.
First of all, I dont know whay it reapets three times?
Because you tell it to. For each subValueKey, print the whole value set. There are three sub-keys, so the complete value set gets printed three times.
Secondly, I want to write a code that if cost = low , then do somthing.
Yaml yaml = new Yaml();
Map<String, Map<String, String>> values =
(Map<String, Map<String, String>>) yaml.load(
new FileInputStream(new File(
"/workspace/servlet-yaml/src/test.yaml")));
final Map<String, String> cdn = values.get("CDN");
// or iterate over all keys like you currently do
final String cost = cdn.get("cost");
// or iterate over all subkeys and compare them to "cost".
// that way, it's easier to handle missing keys.
if ("low".equals(cost)) {
// do something
}

Load data dynamically into HashMap

I am reading data from a CSV file and want to store it into hashMap. There are 3 columns, all of them Strings. I am using this code:
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String,List<String>>();
InputStream inputStream = getResources().openRawResource(R.raw.photographers);
CSVReader csv = new CSVReader(inputStream);
List<String[]> data = csv.read();
List<String> info = new ArrayList<String>();
for(String[] children : data){
info.add(children[1]);
info.add(children[2]);
}
//fill data for the child
for (String[] line : data) {
listDataHeader.add(line[0]);
listDataChild.put(listDataHeader.get(0),info);
}
The listdataChild should keep the info of the 2nd and 3rd column in the CSV. Currently, it's loading the that info more than once. I'd welcome any ideas, thank you!
You could do this with just one iteration.
for (String[] line : data) {
List<String> info = new ArrayList<String>();
info.add(line[1]);
info.add(line[2]);
listDataChild.put(line[0], info);
}
Here, you are iterating through the rows of your csv and creating a new list and adding your second and third columns to that list and adding that list to the map.

No such element in map, why?

I am working on a code in which if I try arrays everything works fine but when i try to solve that example with list it displays
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(Unknown Source)
at com.delete.files.DeleatingFiles.check(DeleatingFiles.java:27)
at com.delete.files.DeleatingFiles.main(DeleatingFiles.java:60)
and the code is :
Map<String, String> map = new HashMap<String, String>();
File folder = new File("F://fileIO/");
if (folder.isDirectory()) {
List<File> filesName = Arrays.asList(folder.listFiles());
Iterator<File> itList = filesName.listIterator();
while (itList.hasNext()) {
map.put(itList.next().getName(), itList.next().toString());
}
System.out.println(map);
}
} else {
System.err.println("something is wrong");
}
}
EDIT 1: All I am trying is to save file name with absolute path as key value pair.
EDIT 2: can't use as Stringnext=itrList.next() as Iterator is of File type.
Now , can anyone tell me the cause of problem ??
Please tell me if there is something wrong.
Thanks.
Your code calls next twice, so if itList has an odd number of elements, the last call would result in NoSuchElementException.
Here is how you can fix your code:
while (itList.hasNext()) {
// Call "next()" once
File next = itList.next();
// Use "next" as many times as you need
map.put(next.getName(), next.toString());
}
is there any other way i can do that without using array?
You can simplify iteration considerably by switching to "for-each" loop:
if (folder.isDirectory()) {
for (File file : folder.listFiles()) {
map.put(file.getName(), file.toString());
}
System.out.println(map);
}
Now your code does not create unnecessary copies of lists, and is free of the NoSuchElementException bug.
In your code map.put(itList.next().getName(), itList.next().toString()); call next() twice even you check itList.hasNext() once.
while (itList.hasNext()) { // Check once
map.put(itList.next().getName(), itList.next().toString()); // next() Call twice here
}
Your code may have to be corrected as like follows
Map<String, String> map = new HashMap<String, String>();
File folder = new File("F://fileIO/");
if (folder.isDirectory()) {
List<File> filesName = Arrays.asList(folder.listFiles());
Iterator<File> itList = filesName.listIterator();
File file;
while (itList.hasNext()) {
file = itList.next();
map.put(file.getName(), file.toString());
}
System.out.println(map);
}
else {
System.err.println("something is wrong");
}
as said, you were calling next twice in each loop. It can also be resolved by using java-8 streams.
Map<String, String> map = new HashMap<String, String>();
File folder = new File("F://fileIO/");
if (folder.isDirectory()) {
map = Arrays.asList(folder.listFiles())
.stream()
.collect(Collectors.toMap(File::getName,
Object::toString));
System.out.println(map);
} else {
System.err.println("Something is wrong!");
}
Map<String, String> map = folder.isDirectory ?
map = Arrays.asList(folder.listFiles())
.stream()
.collect(Collectors.toMap(File::getName,
Object::toString)) :
new HashMap<String, String>();

Setting/Updating multiple document properties in SharePoint 2010 using OpenCMIS

Have tried to search for this almost 'everywhere', but couldn't find a pointer as to how to implement this. Please kindly review my code and offer suggestions on how to set/update ALL documents properties in SharePoint using OpenCMIS. Have created the documents successfully using CMIS, however I'm not able to populate different values for different documents.
For example, a.pdf, b.pdf have different properties. So when I update them, i expect the value to be mapped from array of values assigned to them but at the moment, the same value are being append to all the documents...
Please see my code below, hopefully it will make things clearer:
try {
String [] nextLine =null;
CSVReader reader = new CSVReader(new FileReader(indexFileLocation));
List content = reader.readAll();
for (Object o : content) {
nextLine = (String[]) o;
System.out.println("\n"+ nextLine[2] + "\n"+nextLine[7] + "\n"+ nextLine[6]);
}
//reader.close();
Map <String, Object> newDocProps = new HashMap<String, Object>();
newDocProps.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
newDocProps.put(PropertyIds.NAME, ff.getName());
Document doc = newFolder.createDocument(newDocProps, contentStream, VersioningState.NONE);
CmisObject cmisobject = (Document) session.getObject(doc.getId());
Map<String, Object> pp = new HashMap<String, Object>();
//pp.put(PropertyIds.OBJECT_ID, "Name");
pp.put("WorkflowNumber", nextLine[7]);
pp.put("InvoiceDate", nextLine[2]);
cmisobject.updateProperties(pp);
Any help is appreciated.
#Albert, How are you creating session? It could be an issue with session creation. Please paste your code here to create session.

ArrayList of HashMap elements to Array

How can I get an array of elements in a ArrayList of HashMaps? I have an HashMap with url key on it. The value is a url address. Several HashMaps are stored in a ArrayList. What I want is an array with all url strings. I'm not happy with the solution I found because I think it could be extracted from ArrayList with some manipulation.
// Hashmap for ListView
ArrayList<HashMap<String, String>> itemsList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
jParser.execute(url);
try {
JSONObject json = jParser.get();
items = json.getJSONArray(TAG_ITEMS);
//This is the solution that I want to optimize
urls = new String[items.length()];
// looping through All items
for(int i = 0; i < items.length(); i++){
JSONObject c = items.getJSONObject(i);
// Storing each json item in variable
String title = c.getString(TAG_TITLE);
String description = c.getString(TAG_DESCRIPTION);
String author = c.getString(TAG_AUTHOR);
// Media is another JSONObject
JSONObject m = c.getJSONObject(TAG_MEDIA);
String url = m.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_TITLE, title);
map.put(TAG_DESCRIPTION, description);
map.put(TAG_AUTHOR, author);
map.put(TAG_URL, url);
// Solution
urls[i] = url;
// adding HashList to ArrayList
itemsList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
From what I can deduce from your question, it sounds like you're trying to do the following
// Assuming previously declared and instantiated urls ArrayList with populated values in the nested HashMaps.
ArrayList<HashMap<String, String>> urls;
// Create a new List using HashMap.values from urls.
List<String> urlList = new ArrayList<String>(urls.get(index).values());
urls.get(index).values() will return a Collection view of the values contained in the HashMap at the specified ArrayList index, which will be used to instantiate and populate a new ArrayList.
If you want to obtain all of the values within each of the nested HashMaps or urls, you can do so in a similar manner, but you will need to iterate through the entire urls ArrayList
for (HashMap<String, String> urlValues : urls) {
urlList.addAll(urlValues.values());
}
P.S. Forgive my bad variable names!
It looks like you are building a table. If you can add the Google Guava Library, you could just use the following:
Table<Integer, String, String> Table = HashedBasedTable.create()
See the JavaDoc:
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html

Categories

Resources