I'm trying to extract data from a CSV file, in which I have the following example CSV
timestamp, Column1,column2,column3
2019-05-07 19:17:23,x,y,z
2019-03-30 19:41:33,a,b,c
etc.
currently, my code is as follows:
public static void main(String[]args){
String blah = "file.csv";
File file = new File(blah);
try{
Scanner iterate = new Scanner(file);
iterate.next(); //skips the first line
while(iterate.hasNext()){
String data = iterate.next();
String[] values = data.split(",");
Float nbr = Float.parseFloat(values[2]);
System.out.println(nbr);
}
iterate.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
However, my code is giving me an error
java.lang.ArrayIndexOutOfBoundsException: Index 3 is out of bounds for length 3
My theory here is the split is the problem here. As there is no comma, my program thinks that the array ends with only the first element since there's no comma on the first element (I've tested it with the timestamp column and it seems to work, however, I want to print the values in column 3)
How do I use the split function to get the column1, column2, and column3 values?
import java.util.*;
import java.util.*;
import java.io.*;
public class Sample
{
public static void main(String[] args)
{
String line = "";
String splitBy = ",";
try
{ int i=0;
String file="blah.csv";
BufferedReader br = new BufferedReader(new FileReader(file));
int iteration=0;
while ((line = br.readLine()) != null) //returns a Boolean value
{ if(iteration < 1) {
iteration++;
continue;} //skips the first line
String[] stu = line.split(splitBy);
String time=stu[3];
System.out.println(time);
}
}
catch (IOException e)
{
e.printStackTrace();
}} }
Try this way by using BufferedReader
Input:
timestamp, Column1,column2,column3
2019-05-07 19:17:23,x,y,z
2019-03-30 19:41:33,a,b,c
2019-05-07 19:17:23,x,y,a
2019-03-30 19:41:33,a,b,f
2019-05-07 19:17:23,x,y,x
2019-03-30 19:41:33,a,b,y
Output for this above code is:
z
c
a
f
x
y
A few suggestions:
Use Scanner#nextLine and Scanner#hasNextLine.
Use try-with-resources statement.
Since lines have either whitespace or a comma as the delimiter, use the regex pattern, \s+|, as the parameter to the split method. The regex pattern, \s+|, means one or more whitespace characters or a comma. Alternatively, you can use [\s+,] as the regex pattern.
Demo:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String blah = "file.csv";
File file = new File(blah);
try (Scanner iterate = new Scanner(file)) {
iterate.nextLine(); // skips the first line
while (iterate.hasNextLine()) {
String line = iterate.nextLine();
String[] values = line.split("[\\s+,]");
System.out.println(Arrays.toString(values));
}
}
}
}
Output:
[2019-05-07, 19:17:23, x, y, z]
[2019-03-30, 19:41:33, a, b, c]
Related
I am trying to read the words of a file into a stream and the count the number of times the word "the" appears in the file. I cannot seem to figure out an efficient way of doing this with only streams.
Example: If the file contained a sentence such as: "The boy jumped over the river." the output would be 2
This is what I've tried so far
public static void main(String[] args){
String filename = "input1";
try (Stream<String> words = Files.lines(Paths.get(filename))){
long count = words.filter( w -> w.equalsIgnoreCase("the"))
.count();
System.out.println(count);
} catch (IOException e){
}
}
Just line name suggests Files.lines returns stream of lines not words. If you want to iterate over words I you can use Scanner like
Scanner sc = new Scanner(new File(fileLocation));
while(sc.hasNext()){
String word = sc.next();
//handle word
}
If you really want to use streams you can split each line and then map your stream to those words
try (Stream<String> lines = Files.lines(Paths.get(filename))){
long count = lines
.flatMap(line->Arrays.stream(line.split("\\s+"))) //add this
.filter( w -> w.equalsIgnoreCase("the"))
.count();
System.out.println(count);
} catch (IOException e){
e.printStackTrace();//at least print exception so you would know what wend wrong
}
BTW you shouldn't leave empty catch blocks, at least print exception which was throw so you would have more info about problem.
You could use Java's StreamTokenizer for this purpose.
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamTokenizer;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws IOException {
long theWordCount = 0;
String input = "The boy jumped over the river.";
try (InputStream stream = new ByteArrayInputStream(
input.getBytes(StandardCharsets.UTF_8.name()))) {
StreamTokenizer tokenizer =
new StreamTokenizer(new InputStreamReader(stream));
int tokenType = 0;
while ( (tokenType = tokenizer.nextToken())
!= StreamTokenizer.TT_EOF) {
if (tokenType == StreamTokenizer.TT_WORD) {
String word = tokenizer.sval;
if ("the".equalsIgnoreCase(word)) {
theWordCount++;
}
}
}
}
System.out.println("The word 'the' count is: " + theWordCount);
}
}
Use the stream reader to calculate the number of words.
So, I have a separate program that requires a string of numbers in the format: final static private String INITIAL = "281043765"; (no spaces) This program works perfectly so far with the hard coded assignment of the numbers. I need to, instead of typing the numbers in the code, have the program read a txt file, and assign the numbers in the file to the INITIAL variable
To do this, I'm attempting to use StringTokenizer. My implementation outputs [7, 2, 4, 5, 0, 6, 8, 1, 3]. I need it to output the numbers without the "[]" or the "," or any spaces between each number. Making it look exactly like INITIAL. I'm aware I probably need to put the [] and , as delimiters but the original txt file is purely numbers and I don't believe that will help. Here is my code. (ignore all the comments please)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class test {
//public static String num;
static ArrayList<String> num;
//public static TextFileInput myFile;
public static StringTokenizer myTokens;
//public static String name;
//public static String[] names;
public static String line;
public static void main(String[] args) {
BufferedReader reader = null;
try {
File file = new File("test3_14.txt");
reader = new BufferedReader(new FileReader(file));
num = new ArrayList<String>();
while ((line = reader.readLine())!= null) {
myTokens = new StringTokenizer(line, " ,");
//num = new String[myTokens.countTokens()];
while (myTokens.hasMoreTokens()){
num.add(myTokens.nextToken());
}
}
System.out.println(num);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You are currently printing the default .toString() implementation of ArrayList. Try this instead:
for (String nbr : num) {
System.out.print(nbr)
}
To get rid of the brackets, you have to actually call each item in the ArrayList. Try this just below your System.out.println
for(String number : num)
System.out.print(number);
System.out.println("");
Can you also provide sample input data?
Try Replacing space and , with empty string
line = StringUtils.replaceAll(line, “,” , “”);
line = StringUtils.replaceAll(line, “ “, “”);
System.out.println(line);
hello im trying to take my values in my text file input, and store them in an array then parse those values into usable data and then store those values in a new array. I have the reading of the file but for some reason i cant seem to gain access to the values correctly, i try to parse the values or remove elements but it doesnt seem to change anything in my output when i print the changed array.
please let me know what part im messing up on
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class dataminingp1
{
String[] data = new String[100];
String line;
public void readf() throws IOException
{
FileReader fr = new FileReader("C:\\input.txt");
BufferedReader br = new BufferedReader(fr);
int i = 0;
while ((line = br.readLine()) != null)
{
data[i] = line;
System.out.println(data[i]);
i++;
}
br.close();
System.out.println("Data length: "+data.length);
String[][] root;
List<String> lines = Files.readAllLines(Paths.get("input.txt"), StandardCharsets.UTF_8);
root = new String[lines.size()][];
lines.removeAll(Arrays.asList("", null)); // <- remove empty lines
for(int a =0; a<lines.size(); a++)
{
root[a] = lines.get(a).split(" ");
}
lines.get(0).replace(',', ' ');
//int p = Integer.parseInt(root[0][0]);
System.out.println(lines.get(0));
//System.out.println(p);
}
public static void main(String[] args) throws IOException
{
dataminingp1 sarray = new dataminingp1();
sarray.readf();
}
}
please include any at all sources for any help you give, thank you very much in advance. I really appreciate it.
You need to assign the changes back after changing a String, as String is immutable in java.
String changedLine = lines.get(0).replace(',', ' '); // Assign the modified String returned by replace method to changedLine
lines.set(0, changedLine); // Set the 0th index in the lines with the changedLine
I have the following text file (answers.txt):
Problem A: 23|47|32|20
Problem B: 40|50|30|45
Problem C: 5|8|11|14
Problem D: 20|23|25|30
What I need is something that will read the problem that I tell it(Problem A, Problem B), then read the numbers after it, which are separated by the lines, and print it out like this:
Answers for Problem A: a.23 b.47 c.32 d.20
Does anyone know how this can be done? I've been stuck on it for a while.
Read the lines one by one, split the lines at " " first. The you will get an array with three parts "Problem", "A:" and "23|47|32|20". Then split the third part at "|" so you will get a second array with four parts "23,"47","32","20".
Combine all to get the output you want.
If you want info on how to read lines from a file, or spilt strings then there are billions of tutorials online on how to do that so I wont go into detail on how its done. IM sure you can find them.
Check out this code!
It assumes that you have such file format:
Problem A:
23|7|32|20
Problem B:
40|50|30|45
Problem C:
5|8|11|14
Problem D:
20|23|25|30
because you wrote "numbers after it, which are separated by the lines"
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("answers.txt"));
List<String> dataList = new ArrayList<String>();
while(sc.hasNextLine()){
dataList.add(sc.nextLine());
}
System.out.println(dataList);
Map<String,String> map = new HashMap<String,String>();
for(int i=0;i<dataList.size();i=i+2){
map.put(dataList.get(i),dataList.get(i+1));
}
for(Entry<String,String> en:map.entrySet()){
System.out.println(en.getKey()+" : "+en.getValue());
}
String problemC = map.get("Problem C:");
String splitted[] = problemC.split("\\|");
System.out.println("Get me problem C: "+String.format("a:%s, b:%s, c:%s, d:%s",splitted[0],splitted[1],splitted[2],splitted[3]));
}
}
Hope this helps!
public static void main(String args[])
{
BufferedReader br = new BufferedReader(new FileReader(new File("answers.txt")));
String lineRead = null;
String problem = "Problem A";//Get this from user Input
List<String> numberData = new ArrayList<String>();
while((lineRead = br.readLine())!=null)
{
if(lineRead.contains(problem))
{
StringTokenizer st = new StringTokenizer(lineRead,":");
String problemPart = st.nextToken();
String numbersPart = st.nextToken();
st = new StringTokenizer(lineRead,"|");
while(st.hasMoreTokens())
{
String number = st.nextToken();
System.out.println("Number is: " + number);
numberData.add(number);
}
break;
}
}
System.out.println("Answers for " + problem + " : " + numberData );
}
Read the lines one by one, split the lines with :. The you will get an array with two parts "Problem A:" and "23|47|32|20". Then split the second part at "|" so you will get a second array with four parts "23,"47","32","20".
Combining all this you will get the output you want.
Cheers!
Use java.util.Scanner and you can filter the integers in the file.
Scanner s = new Scanner (new File ("answers.txt")).useDelimiter("\\s+");
while (s.hasNext()) {
if (s.hasNextInt()) { // check if next token is integer
System.out.print(s.nextInt());
} else {
s.next(); // else read the next token
}
}
Do you know how to read line by line ? If not , chect it How to read a large text file line by line in java?
To sub your string data there have many ways to do. You can sub as you wish. Here for my code..
String data = yourReader.readLine();
String problem = data.substring("Problem".length(), data.indexOf(":"));
System.err.println("Problem is " + problem);
data = data.substring(data.indexOf(":") + 2, data.length());
String[] temp = data.split("\\|");
for (String result : temp) {
System.out.println(result);
}
Assuming there are always four possible answers as in your Example:
// read complete file in fileAsString
String regex = "^(Problem \\w+): (\\d+)\\|(\\d+)\\|(\\d+)\\|(\\d+)$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(fileAsString);
//and so on, read all the Problems using matcher.find() and matcher.group(int) to get the parts
// put in a Map maybe?
// output the one you want...
I might suggest creating a simple data type for the purpose of organization:
public class ProblemAnswer {
private final String problem;
private final String[] answers;
public ProblemAnswer(String problem, String[] answers) {
this.problem = problem;
this.answers = new String[answers.length];
for (int i = 0; i < answers.length; i++) {
this.answers[i] = answers[i];
}
}
public String getProblem() {
return this.problem;
}
public String[] getAnswers() {
return this.answers;
}
public String getA() {
return this.answers[0];
}
public String getB() {
return this.answers[1];
}
public String getC() {
return this.answers[2];
}
public String getD() {
return this.answers[3];
}
}
Then the reading from the text file would look something like this:
public void read() {
Scanner s = new Scanner("answers.txt");
ArrayList<String> lines = new ArrayList<String>();
while (s.hasNext()) {
lines.add(s.nextLine());//first separate by line
}
ProblemAnswer[] answerKey = new ProblemAnswer[lines.size()];
for (int i = 0; i < lines.size(); i++) {
String[] divide = lines.get(i).split(": "); //0 is the problem name, 1 is the list
//of answers
String[] answers = divide[1].split("|"); //an array of the answers to a given
//question
answerKey[i] = new ProblemAnswer(divide[0], answers); //add a new ProblemAnswer
//object to the key
}
}
Now that leaves you with an answer key with ProblemAnswer objects which is easily checked
with a simple .equals() comparison on the getProblem() method, and whatever index is matched, you have all the answers neatly arranged right within that same object.
I want make a game of life clone using text files to specify my starting board, then write the finished board to a new text file in a similar format. E.g. load this:
Board in:
wbbbw
bbbbb
wwwww
wbwbw
bwbwb
from a file, then output something like this:
Board out:
wbbbw
bbbbb
wwwww
wwwww
bwbwb
I do this by making a 2D array (char[][] board) of characters, reading the file line by line into a string, and using String.charAt() to access each character and store it in the array.
Afterward, I convert each element of board (i.e., board[0], board[1], etc.), back to a string using String.valueOf(), and write that to a new line in the second file.
Please tell me I'm an idiot for doing this and that there is a better way to go through the file -> string -> array -> string -> file process.
You can use String.toCharArray() for each line while reading the file.
char[][] board = new char[5][];
int i = 0;
while((line = buffRdr.readLine()) != null) {
board[i++] = line.toCharArray();
}
And while writing either String.valueOf() or java.util.Arrays.toString().
for(int i=0; i<board.length; i++) {
//write Arrays.toString(board[i]);
}
// Remember to handle whitespace chars in array
char[] row = "wbbbw bbbbb wwwww wbwbw bwbwb".toCharArray()
Everything else seems good.
Why not use an already existing text format such as JSON instead of inventing your own?
There are tons of JSON parsers out there that can read and write two dimensional arrays.
You get both the benefit of easy reading directly from the file(as with your original method) and the benefit of not having to parse an annoying string format.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class GameOfLife
{
private String mFilename;
private ArrayList<String> mLines;
public GameOfLife(String filename)
{
mFilename = filename;
read();
}
public char get(int x, int y)
{
String line = mLines.get(y);
return line.charAt(x);
}
public void set(char c, int x, int y)
{
String line = mLines.get(y);
String replacement = line.substring(0, x) + c + line.substring(x + 1, line.length());
mLines.set(y, replacement);
}
private void read()
{
mLines = new ArrayList<String>();
try
{
BufferedReader in = new BufferedReader(new FileReader(mFilename));
String line = in.readLine();
while (line != null)
{
mLines.add(line);
line = in.readLine();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void write()
{
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(mFilename));
for (String line : mLines)
{
out.write(line + "\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}