I'm having some trouble trying to turn an excel file into an arraylist or just an array containing information stored in different cells.
The information is stored in excel like this example:
Owner's info ; Car's Owner ; Car's seller;
Date; Car brand ; Number of doors ; Car license plate ; Car color ;
Price
2.3.2013 ; Fiat ; 4 ; 23-21-AA ; black ; 10.000
2.1.2014 ; Renault ; 4 ; 23-12-BA ; blue ; 25.000
I will need to access information such as getBrand() , getLicense etc, so I wanted to store this different information into arraylists, OwnerInfo[ Owner[] , Seller[] ]
Later I would like to sum the car prices or something else, and because of that I'd like to access CarInfo[6] and sum them all.
I'm kinda lost on this, need some suggestions or tips.
public static void main(String args[]) {
try {
FileInputStream fstream = new FileInputStream(
"file.csv");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] tokens = strLine.split(";");
for (int i = 0; i < tokens.length; i++) {
System.out.println(tokens[i]);
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Another question is when I use
for (int i = 0; i < tokens.length; i++) {
System.out.println(tokens[0]);
}
It will print first column of excel (.csv) , but if I print tokens[1] it won't print anything. Why's that?
Also, if I do the same thing on a .txt file it will print the second "column".
May be you could re-consider your "design". Now what you are doing is, store each line in a java array. This is not convenient for you later processing (as you described).
You can think about the following two alternatives:
If you love array, you can build a map<String, String[] (or number)> the first string, is the label of your header line, like number of door, car owner... of course you can use some short name for that., and the arrays, are the columns. Thus, if you want some column data, you just map.get(name). If you could use third party lib, consider some extended map type like multimap from guava to ease your implementation.
You can build your own type (class) for each row, like CarData, and generate each CarData object for each row, pack them into a Collection. If it was required, you could build some helper method to get the interesting values from the list.
personally I prefer the 2nd one, since it is flexible. Think about if you have requirement in future like sorting (Comparator), outputing line in other format, reporting .....
I hope I understood your problem right and hope the text above helps.
You can use https://github.com/CyborTronik/fluent-ssv for transforming CSV to beans. In your case you need to provide values separator to stream builder.
So you will have something like:
carsStream = new SsvStreamBuilder<Car>()
.withSeparator(";")
.forEntity(Car.class)
.stream("~/path/to/file");
And voila, use stream of beans instead of arrays.
Related
I have a file of alphanumeric VIN numbers from vehicles (saved as strings). I need to parse through this file and determine
1) Is a VIN duplicated? If so, how many times
2) Write the duplicated VIN and the total number of duplicates to a text file
I have gotten it to work using the brute force method dual nested For loops. Am looking for a more elegant way to parse the strings. I'm using Java 7 in NetBeans 8.2 and it doesn't appear to like using the .set or hashmap.
Constraints
1) The VINs may be in any order
2) The duplicates can be scattered through the file at random
/* a) Open input and output files
*/
try {
inputStream = new BufferedReader(new FileReader(fileName));//csv file
outputStream = new PrintWriter(new FileWriter("DuplicateVINs.txt"));
/* b) Read in file line by line
then slice out the 17 digit VIN from the extra data I don't care about
*/
while ((thisLine = inputStream.readLine()) != null) {
l = thisLine.substring(1, 18);
linesVIN.add(l.split(","));//why does this split have to be here?
}
/*c) Now that the List is full calculate its size and then write to array of strings
*/
String[][] inputArray = new String[linesVIN.size()][];
i=linesVIN.size();
System.out.println(i);
linesVIN.toArray(inputArray);
/* d) Will use two nested For loos to look for duplicates
*/
countj=0;
countk=0;
for (int j = 1;j<=i-1; j++){ //j loop
duplicateVIN=Arrays.toString(inputArray[j]);
for(int k=1;k<=i-1;k++){
if(duplicateVIN.equals(Arrays.toString(inputArray[k]))){
countk=countk+1;
foundFlag=true;
} else{
//
if(countk>=2){
//if(j!=k){
System.out.println(duplicateVIN + countk);
//} // see if removes the first duplicate
}
foundFlag=false;
countk=0;
}
} //ends k loop
countj=j;
} //ends j loop
} //Completes the try
[2q3CDZC90JH1qqqqq], 3
[2q4RC1NG1JR1qqqqq], 4
[2q3CDZC96KH1qqqqq], 2
[1q4PJMDN8KD1qqqqq], 7
I'm using Java 7 in NetBeans 8.2 and it doesn't appear to like using the .set or hashmap.
Your first step should be to figure out what you're doing wrong with a map. A hashmap is the perfect solution for this problem, and is really what you should be using.
Here's a broad example of how the solution would work, using the information you provided.
Map<String,Integer> countMap = new HashMap<String,Integer>();
while ((thisLine = inputStream.readLine()) != null) {
l = thisLine.substring(1, 18);
if(countMap.containsKey(l)){
countMap.put(l, countMap.get(l)+1);
}else{
countMap.put(l,1);
}
}
I'm assuming that the while loop your provided is properly iterating over all VIN numbers.
After this while loop is completed you would just need to output the values of each key, similar to this:
for(String vin : countMap.keySet()){
System.out.println("VIN: "+vin+" COUNT: "+countMap.get(vin));
}
If I've read your problem correctly, there is no need for a nested loop.
I'm new to writing java code as such. I have experience writing code in scripting type languages. I'm trying to rewrite a piece of code I had in python in java.
Python code below -
import pandas as pd
myFile = 'dataFile'
df = pd.DataFrame(pd.read_csv(myFile,skiprows=0))
inData = df.as_matrix()
I'm looking for a method in java that is equivalent to as_matrix in python. This function converts the data frame into a matrix.
I did look up for sometime now but can't find a method as such that does the conversion like in python. Is there a 3rd party library or something on those lines I could use? Any direction would help me a lot please. Thank you heaps.
What you want to do is really simple and requires minimal code on your part, therefore I suggest you code it yourself. Here is an example implementation:
List<String[]> rowList = new ArrayList<String[]>();
try (BufferedReader br = new BufferedReader(new FileReader("pathtocsvfile.csv"))) {
String line;
while ((line = br.readLine()) != null) {
String[] lineItems = line.split(",");
rowList.add(lineItems);
}
br.close();
}
catch(Exception e){
// Handle any I/O problems
}
String[][] matrix = new String[rowList.size()][];
for (int i = 0; i < rowList.size(); i++) {
String[] row = rowList.get(i);
matrix[i] = row;
}
What this does is really simple: It opens a buffered reader that will read the csv file line by line and paste the contents to an array of Strings after splitting them based on comma (which is your delimiter). Then it will add them to a list of arrays. I know this might not be perfect, so afterwards I take the contents of that list of arrays and turn it into a neat 2D matrix. Hope this helps.
Hint: there are a lot of improvements that could be made to this little piece of code (i.e. take care of trailing and leading spaces, add user-defined delimiters etc.), but this should be a good starting point.
I am in the process of making a java application that reads through a .ttl file line by line and creates a graphml file to represent the ontology.
I am having some trouble figuring out how to enumerate a certain section.
I am using BufferedReader to read each line.
For example, I have the following:
else if (line.contains("owl:oneOf")){
// insert code to enumerate list contained in ( )
}
And this is what the .ttl looks like for oneOf:
owl:oneOf (GUIFlow:ExactlyOne
GUIFlow:OneOrMore
GUIFlow:ZeroOrMore
GUIFlow:ZeroOrOne )
I need to return those 4 objects as one list, to be used as part of a graphical representation of an ontology.
Apparently you have some kind of loop going through the file. Here are some ideas:
1) Introduce a "state" into the loop so that upon reading the next line it will know that it's actually inside the oneOf list. A dynamic array to store the list can serve as the state. You create the list when encountering the (, and you send the list wherever it is needed when encountering the ) and then delete the list after that. A complication is that according to your source format you will have to create the list before adding values to it, and process and delete the list after adding values, because ( and ) are on the same lines as actual values.
Vector<String> oneOfList = null;
while(reader.ready()){
String line=reader.readLine();
if(line.contains("foo")){
...
}
else if (line.contains("owl:oneOf")){
oneOfList = new Vector<String>();
}
if(oneOfList!=null){
String str = line.trim();
int a = str.indexOf("("); // -1 if not found, OK
int b = str.indexOf(")");
if(b<0) b=str.length();
oneOfList.add(str.substring(a+1,b).trim());
}
if (line.contains(")")){
storeOneOf(oneOfList);
oneOfList=null;
}
}
2) When the oneOf header is encountered, create another small loop to read its values. A possible drawback may be that you end up with two loops iterating over the file and two calls to reader.readLine, which may complicate things or may not.
while(reader.ready()){
String line=reader.readLine();
if(line.contains("foo")){
...
}
else if (line.contains("owl:oneOf")){
Vector<String> oneOfList = new Vector<String>();
while(true){
String str = line.trim();
int a = str.indexOf("("); // -1 if not found, OK
int b = str.indexOf(")");
int c = (b>=0) ? b : str.length();
oneOfList.add(str.substring(a+1,c).trim());
if(b>=0) break;
line=reader.readLine();
}
storeOneOf(oneOfList);
}
}
3) The above algorithms rely on the fact that the header, the ( and the first value are on the same line, etc. If the source file is formatted a bit differently, the parsing will fail. A more flexible approach may be to use StreamTokenizer which automatically ignores whitespace and separates the text into words and stand-alone symbols:
StreamTokenizer tokzr=new StreamTokenizer(reader);
tokzr.wordChars(':',':');
while( tokzr.nextToken() != tokzr.TT_EOF ){
if( tokzr.ttype==tokzr.TT_WORD && tokzr.sval.equals("foo") ){
...
}
else if ( tokzr.ttype==tokzr.TT_WORD && tokzr.sval.equals("owl:oneOf") ){
if(tokzr.nextToken()!='(') throw new Exception("\"(\" expected");
Vector<String> oneOfList = new Vector<String>();
while(tokzr.nextToken() == tokzr.TT_WORD){
oneOfList.add(tokzr.sval);
}
storeOneOf(oneOfList);
if(tokzr.ttype!=')') throw new Exception("\")\" expected");
}
}
Have you considered (and rejected) existing solutions e.g: Jena ?
I'm trying to figure out how to read data from a file, using an array. The data in the file is listed like this:
Clarkson 80000
Seacrest 100000
Dunkleman 75000
...
I want to store that information using an array. Currently I have something like this to read the data and use it:
String name1 = in1.next();
int vote1 = in1.nextInt();
//System.out.println(name1 +" " + vote1);
String name2 = in1.next();
int vote2 = in1.nextInt();
//System.out.println(name2 +" " + vote2);
String name3 = in1.next();
int vote3 = in1.nextInt();
...
//for all names
Problem is, the way I'm doing it means I can never manipulate the file data for more contestants or whatnot.
While I can use this way and handle all the math within different methods and get the expected output...its really inefficient I think.
Output expected:
American Idol Fake Results for 2099
Idol Name Votes Received % of Total Votes
__________________________________________________
Clarkson 80,000 14.4%
Seacrest 100,000 18.0%
Dunkleman 75,000 13.5%
Cowell 110,000 19.7%
Abdul 125,000 22.4%
Jackson 67,000 12.0%
Total Votes 557,000
The winner is Abdul!
I figure reading input file data into arrays is likely easy using java.io.BufferedReader is there a way not to use that?
I looked at this: Java: How to read a text file but I'm stuck thinking this is a different implementation.
I want to try to process all the information through understandable arrays and maybe at least 2-3 methods (in addition to the main method that reads and stores all data for runtime). But say I want to use that data and find percentages and stuff (like the output). Figure out the winner...and maybe even alphabetize the results!
I want to try something and learn how the code works to get a feel of the concept at hand. ;c
int i=0
while (in.hasNextLine()) {
name = in.nextLine();
vote = in.nextInt();
//Do whatever here: print, save name and vote, etc..
//f.e: create an array and save info there. Assuming both name and vote are
//string, create a 2d String array.
array[i][0]=name;
array[i][1]=vote;
//if you want to individually store name and votes, create two arrays.
nameArray[i] = name;
voteArray[i] = vote;
i++;
}
This will loop until he automatically finds you don't have any more lines to read. Inside the loop, you can do anything you want (Print name and votes, etc..). In this case, you save all the values into the array[][].
array[][] will be this:
array[0][0]= Clarkson
array[0][1]= 80,000
array[1][0]= Seacrest
array[1][1]= 100,000
...and so on.
Also, I can see that you have to do some maths. So, if you save it as a String, you should convert it to double this way:
double votesInDouble= Double.parseDouble(array[linePosition][1]);
You have several options:
create a Class to represent your File data, then have an array of those Objects
maintain two arrays in parallel, one of the names and the other of the votes
Use a Map, where the name of the person is the key and the number of votes is the value
a) gives you direct access like an array
b) you don't need to create a class
Option 1:
public class Idol
{
private String name;
private int votes;
public Idol(String name, int votes)
{
// ...
}
}
int index = 0;
Idol[] idols = new Idol[SIZE];
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
//create Idol
Idol i = new Idol(name1, vote1);
// insert into array, increment index
idols[index++] = i;
Option 2:
int index = 0;
String[] names = new String[SIZE];
int[] votes = new int[SIZE];
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
// insert into arrays
names[index] = name1;
votes[index++] = vote1;
Option 3:
// create Map
Map<String, Integer> idolMap = new HashMap<>();
// read from file
String name1 = in1.next();
int vote1 = in1.nextInt();
// insert into Map
idolMap.put(name1, vote1);
Now you can go back any manipulate the data to your hearts content.
i dont't use java very often and now i got some Problem.
I want to read a CSV file like this one:
A,B,C,D
A,B,F,K
E,F,S,A
A,B,C,S
A,C,C,S
Java don't know dynamic arrays, so i choose an ArrayList. This works so far. The Problem is:
How can I store the ArrayList? I think an other ArrayList would help.
This is what I got:
BufferedReader reader = new BufferedReader(
new InputStreamReader(this.getClass().getResourceAsStream(
"../data/" + filename + ".csv")));
List rows = new ArrayList();
String line;
while ((line = reader.readLine()) != null) {
rows.add(Arrays.asList(line.split(",")));
}
Now I get an ArrayList with a size of 5 for rows.size().
How do I get row[0][0] for example?
What do I want to do? The Problem is i want to find the same row except the last column.
For example i want to find row 0 and row 3.
thank you very much
Thank you all! You helped me a lot. =) Maybe Java and I will become friends =) THANKS!
You don't need to know the row size in advance, String.split() returns a String array:
List<String[]> rows = new ArrayList<String[]>();
String line = null;
while((line = reader.readLine()) != null)
rows.add(line.split(",", -1));
To access a specific row:
int len = rows.get(0).length;
String val = rows.get(0)[0];
Also, are you always comparing by the entire row except the last column? You could just take off the last value (line.replaceFirst(",.*?$", "")) and compare the rows as strings (have to be careful of whitespace and other formatting, of course).
A slightly different way:
Set<String> rows = new HashSet<String>();
String line = null;
while((line = reader.readLine()) != null){
if(!rows.add(line.substring(0, line.lastIndexOf(','))))
System.out.println("duplicate found: " + line);
}
Of course, modify as necessary if you actually need to capture the matching lines.
You'll need to declare an ArrayList of arrays. Asuming that csv file has a known number of columns, the only dynamic list needed here are the "rows" of your "table", formed by an ArrayList(rows) of arrays char[] (columns). (If not, then an ArrayList of ArrayList is fine).
It's just like a 2D table in any other language: an array of arrays. Just that in this case one of the arrays needs to be dynamic.
To read the file you'll need two loops. One that reads each line, just as you're doing, and another one that reads char per char.
Just a quick note: if you are going to declare an array like this:
char[] row = new char[5];
and then going to add each row to the ArrayList like this:
yourList.add(row);
You will have a list full of pointers to the same array. You'll need to use the .clone() method like this:
yourList.add(row.clone());
To access it like table[1][2], you'll need to use arraylist.get(1).get(2);