ArrayList confusion - java

The code below is my attempt to read from a file of strings, read through each line until a ':' is found then store + print everything after that. however The print function prints out everything that I read in from the file. Can someone spot where I'm going wrong? thanks
edit: every line is in this format "Some text here:More text here"
public void openFile() {
try {
scanner = new BufferedReader(new FileReader("calendar.ics"));
} catch (Exception e) {
System.out.println("Could not open file");
}
}
public void readFile() {
ArrayList<String> vals = new ArrayList<String>();
String test;
try {
while ((line = scanner.readLine()) != null)
{
int indexOfComma = line.indexOf("\\:"); // returns firstIndexOf ':'
test = line.substring(indexOfComma+1); // test to be everything after ':'
vals.add(test); // add values to vals
}
} catch(Exception ex){ }
for(int i=0; i<vals.size(); i++){
System.out.println(vals.get(i));
}
}

You don't need to escape your colon.
line.indexOf("\\:");
Change the above line to: -
line.indexOf(":");
Because, that will search for \\:, and if not found return the value -1.
test = line.substring(indexOfComma+1);
So, if your indexComma is -1, which will certainly be, if your string does not contain - \\:, then your above line becomes: -
line.substring(0); // same as whole string
As a suggestion, you should have abstract type as the type of reference when declaring your list. So, you should use List instead of ArrayList on the LHS of the List declaration: -
List<String> vals = new ArrayList<String>();

Related

Read the each string text from file in java

I am new in java. I just wants to read each string in java and print it on console.
Code:
public static void main(String[] args) throws Exception {
File file = new File("/Users/OntologyFile.txt");
try {
FileInputStream fstream = new FileInputStream(file);
BufferedReader infile = new BufferedReader(new InputStreamReader(
fstream));
String data = new String();
while ((data = infile.readLine()) != null) { // use if for reading just 1 line
System.out.println(""+data);
}
} catch (IOException e) {
// Error
}
}
If file contains:
Add label abc to xyz
Add instance cdd to pqr
I want to read each word from file and print it to a new line, e.g.
Add
label
abc
...
And afterwards, I want to extract the index of a specific string, for instance get the index of abc.
Can anyone please help me?
It sounds like you want to be able to do two things:
Print all words inside the file
Search the index of a specific word
In that case, I would suggest scanning all lines, splitting by any whitespace character (space, tab, etc.) and storing in a collection so you can later on search for it. Not the question is - can you have repeats and in that case which index would you like to print? The first? The last? All of them?
Assuming words are unique, you can simply do:
public static void main(String[] args) throws Exception {
File file = new File("/Users/OntologyFile.txt");
ArrayList<String> words = new ArrayList<String>();
try {
FileInputStream fstream = new FileInputStream(file);
BufferedReader infile = new BufferedReader(new InputStreamReader(
fstream));
String data = null;
while ((data = infile.readLine()) != null) {
for (String word : data.split("\\s+") {
words.add(word);
System.out.println(word);
}
}
} catch (IOException e) {
// Error
}
// search for the index of abc:
for (int i = 0; i < words.size(); i++) {
if (words.get(i).equals("abc")) {
System.out.println("abc index is " + i);
break;
}
}
}
If you don't break, it'll print every index of abc (if words are not unique). You could of course optimize it more if the set of words is very large, but for a small amount of data, this should suffice.
Of course, if you know in advance which words' indices you'd like to print, you could forego the extra data structure (the ArrayList) and simply print that as you scan the file, unless you want the printings (of words and specific indices) to be separate in output.
Split the String received for any whitespace with the regex \\s+ and print out the resultant data with a for loop.
public static void main(String[] args) { // Don't make main throw an exception
File file = new File("/Users/OntologyFile.txt");
try {
FileInputStream fstream = new FileInputStream(file);
BufferedReader infile = new BufferedReader(new InputStreamReader(fstream));
String data;
while ((data = infile.readLine()) != null) {
String[] words = data.split("\\s+"); // Split on whitespace
for (String word : words) { // Iterate through info
System.out.println(word); // Print it
}
}
} catch (IOException e) {
// Probably best to actually have this on there
System.err.println("Error found.");
e.printStackTrace();
}
}
Just add a for-each loop before printing the output :-
while ((data = infile.readLine()) != null) { // use if for reading just 1 line
for(String temp : data.split(" "))
System.out.println(temp); // no need to concatenate the empty string.
}
This will automatically print the individual strings, obtained from each String line read from the file, in a new line.
And afterwards, I want to extract the index of a specific string, for
instance get the index of abc.
I don't know what index are you actually talking about. But, if you want to take the index from the individual lines being read, then add a temporary variable with count initialised to 0.
Increment it till d equals abc here. Like,
int count = 0;
for(String temp : data.split(" ")){
count++;
if("abc".equals(temp))
System.out.println("Index of abc is : "+count);
System.out.println(temp);
}
Use Split() Function available in Class String.. You may manipulate according to your need.
or
use length keyword to iterate throughout the complete line
and if any non- alphabet character get the substring()and write it to the new line.
List<String> words = new ArrayList<String>();
while ((data = infile.readLine()) != null) {
for(String d : data.split(" ")) {
System.out.println(""+d);
}
words.addAll(Arrays.asList(data));
}
//words List will hold all the words. Do words.indexOf("abc") to get index
if(words.indexOf("abc") < 0) {
System.out.println("word not present");
} else {
System.out.println("word present at index " + words.indexOf("abc"))
}

Reading textfile line by line and put in object array

I have to make an EPG app using java, but I am kind of new in programming and it's due tomorrow and it's still not working properly.
I have a question about a small part: I have to read the programs from a text file. Each line contains multiple things, the channel, the title of the program, a subtitle, a category, etcetera.
I have to make sure that I can read the separate parts of each line, but it's not really working, it's only printing the parts from the first line.
I am trying, but I can't find why it's not printing all the parts from all the lines in stead of printing only the parts from the first line. Here's the code:
BufferedReader reader = new BufferedReader(newFileReader(filepath));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
}
String[] parts = line.split("\\|", -1);
for(int i = 0; i < parts.length; i++) {
System.out.println(parts[i]);
}
reader.close();
Does anybody know how to get all the lines in stead of only the first?
Thank you!
readLine() only reads one line, so you need to loop it, as you said.
BUT with reading to the String inside of the while loop you always overwrite that String.
You would need to declare the String above the while loop that you can access it from outside, too.
BTW, it seems that your braces for the if don't match.
Anyway, I'd fill the information into an ArrayList, look below:
List<String> list = new ArrayList<>();
String content;
// readLine() and close() may throw errors, so they require you to catch it…
try {
while ((content = reader.readLine()) != null) {
list.add(content);
}
reader.close();
} catch (IOException e) {
// This just prints the error log to the console if something goes wrong
e.printStackTrace();
}
// Now proceed with your list, e.g. retrieve first item and split
String[] parts = list.get(0).split("\\|", -1);
// You can simplify the for loop like this,
// you call this for each:
for (String s : parts) {
System.out.println(s);
}
Use apache commons lib
File file = new File("test.txt");
List<String> lines = FileUtils.readLines(file);
As ArrayList is Dynamic,try,
private static List<String> readFile(String filepath) {
String line = null;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader(filepath));
while((line = reader.readLine()) != null){
list.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}

Reading a .txt file and excluding certain elements

In my journey to complete this program I've run into a little hitch with one of my methods. The method I am writing reads a certain .txt file and creates a HashMap and sets every word found as a Key and the amount of time it appears is its Value. I have managed to figure this out for another method, but this time, the .txt file the method is reading is in a weird format. Specifically:
more 2
morning's 1
most 3
mostly 1
mythology. 1
native 1
nearly 2
northern 1
occupying 1
of 29
off 1
And so on.
Right now, the method is returning only one line in the file.
Here is my code for the method:
public static HashMap<String,Integer> readVocabulary(String fileName) {
// Declare the HashMap to be returned
HashMap<String, Integer> wordCount = new HashMap();
String toRead = fileName;
try {
FileReader reader = new FileReader(toRead);
BufferedReader br = new BufferedReader(reader);
// The BufferedReader reads the lines
String line = br.readLine();
// Split the line into a String array to loop through
String[] words = line.split(" ");
// for loop goes through every word
for (int i = 0; i < words.length; i++) {
// Case if the HashMap already contains the key.
// If so, just increments the value.
if (wordCount.containsKey(words[i])) {
int n = wordCount.get(words[i]);
wordCount.put(words[i], ++n);
}
// Otherwise, puts the word into the HashMap
else {
wordCount.put(words[i], 1);
}
}
br.close();
}
// Catching the file not found error
// and any other errors
catch (FileNotFoundException fnfe) {
System.err.println("File not found.");
}
catch (Exception e) {
System.err.print(e);
}
return wordCount;
}
The issue is that I'm not sure how to get the method to ignore the 2's and 1's and 29's of the .txt file. I attempted making an 'else if' statement to catch all of these cases but there are too many. Is there a way for me to catch all the ints from say, 1-100, and exlude them from being Keys in the HashMap? I've searched online but have turned up something.
Thank you for any help you can give!
How about just doing wordCount.put(words[0],1) into wordcount for every line, after you've done the split. If the pattern is always "word number", you only need the first item from the split array.
Update after some back and forth
public static HashMap<String,Integer> readVocabulary(String toRead)
{
// Declare the HashMap to be returned
HashMap<String, Integer> wordCount = new HashMap<String, Integer>();
String line = null;
String[] words = null;
int lineNumber = 0;
FileReader reader = null;
BufferedReader br = null;
try {
reader = new FileReader(toRead);
br = new BufferedReader(reader);
// Split the line into a String array to loop through
while ((line = br.readLine()) != null) {
lineNumber++;
words = line.split(" ");
if (words.length == 2) {
if (wordCount.containsKey(words[0]))
{
int n = wordCount.get(words[0]);
wordCount.put(words[0], ++n);
}
// Otherwise, puts the word into the HashMap
else
{
boolean word2IsInteger = true;
try
{
Integer.parseInt(words[1]);
}
catch(NumberFormatException nfe)
{
word2IsInteger = false;
}
if (word2IsInteger) {
wordCount.put(words[0], Integer.parseInt(words[1]));
}
}
}
}
br.close();
br = null;
reader.close();
reader = null;
}
// Catching the file not found error
// and any other errors
catch (FileNotFoundException fnfe) {
System.err.println("File not found.");
}
catch (Exception e) {
System.err.print(e);
}
return wordCount;
}
To check if a String contains a only digits use String´s matches() method, e.g.
if (!words[i].matches("^\\d+$")){
// NOT a String containing only digits
}
This wont require checking exceptions and it doesnt matter if the number wouldnt fit inside an Integer.
Option 1: Ignore numbers separated by whitespace
Use Integer.parseInt() or Double.parseInt() and catch the exception.
// for loop goes through every word
for (int i = 0; i < words.length; i++) {
try {
int wordAsInt = Integer.parseInt(words[i]);
} catch(NumberFormatException e) {
// Case if the HashMap already contains the key.
// If so, just increments the value.
if (wordCount.containsKey(words[i])) {
int n = wordCount.get(words[i]);
wordCount.put(words[i], ++n);
}
// Otherwise, puts the word into the HashMap
else {
wordCount.put(words[i], 1);
}
}
}
There is a Double.parseDouble(String) method, which you could use in place of Integer.parseInt(String) above if you wanted to eliminate all numbers, not just integers.
Option 2: Ignore numbers everywhere
Another option is to parse your input one character at a time and ignore any character that isn't a letter. When you scan whitespace, then you could add the word generated by the characters just scanned in to your HashMap. Unlike the methods mentioned above, scanning by character would allow you to ignore numbers even if they appear immediately next to other characters.

Save String with random number of lines to single line array JAVA

So here is the method which is reading from the file, it then splits the information by the # sign. which is where a new month begins in the text file
public static String readPurchaseOrder(Scanner sc) {
final String DELIMITER = "#";
try {
while (sc.hasNext()) {
sc.useDelimiter(DELIMITER);
String data = sc.next();
return data;
}
} catch (Exception e) {
System.out.println(e);
}
sc.close();
return null;
}
The text file contains information shown below up to the 12th month
04/01/12#PNW-1234#PA/1234#10
15/01/12#BSE-5566#bT/4674#5#
08/02/12#PNE-3456#Xk/8536#1#
07/03/12#PEA-4567#ZR/7413#3
09/03/12#ESE-6329#HY/7195#30#
03/04/12#ESE-5577#LR/4992#12
23/04/12#PNW-1235#HY/7195#2#
09/05/12#ESE-6329#PV/5732#6
25/05/12#BSE-5566#PV/5732#10#
08/06/12#PNE-3457#kD/9767#1
31/06/12#EMI-6329#ZR/7413#10#
03/07/12#EMI-6329#PV/5732#12
25/07/12#BSE-5566#bT/4674#5#
I am using this to output the information from the file split by the #
for (int i = 0; i <12; i ++){
String str[] = InputFileData.readPurchaseOrder(sC).split("\\n");
for(String s : str){
System.out.println(s);
}
It outputs the data like this
04/01/12#PNW-1234#PA/1234#10
15/01/12#BSE-5566#bT/4674#5
08/02/12#PNE-3456#Xk/8536#1
07/03/12#PEA-4567#ZR/7413#3
09/03/12#ESE-6329#HY/7195#30
03/04/12#ESE-5577#LR/4992#12
23/04/12#PNW-1235#HY/7195#2
09/05/12#ESE-6329#PV/5732#6
25/05/12#BSE-5566#PV/5732#10
I want to store each individual line in an array, so I can then further split up the line to its each respective variables
If you would like to collect the results in an array, one line per array element, the easiest way to do it is to use a list (since you don't know in advance the number of lines), and then convert it to an array. The size of an array has to be declared in advance, so you want to use a more flexible data structure if you don't know how big it's going to be.
public static String[] readPurchaseOrder(Scanner sc) {
final String DELIMITER = "#";
List<String> results = new ArrayList<>();
try {
while (sc.hasNext()) {
sc.useDelimiter(DELIMITER);
String data = sc.next();
results.add(data); // add the line to the list
}
} catch (Exception e) {
System.out.println(e);
}
sc.close();
// convert the list to an array and return it.
return results.toArray(new String[results.size()]);
}

Initialising an array of objects from a CSV file

This problem takes a bit of explaining, I'll try to be as concise as possible:
I have am trying to initalise an array of Can objects, these objects only have 2 fields (both Strings): name, manufacturer
I am trying to initialise the fields by reading from a CSV file with the following format:
Tomatoes,Heinz
Legumes,Jerry
(no space between the lines, it's being formatted like that on this site for some reason)
The first string in each row is the value I want to be the name, the 2nd is the manufacturer.
So I've created a method to read each line of the CSV, which passes each line to a tokenizer method to extract single values:
private void readFile (String inFilename) {
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int lineNum;
String line;
try {
fileStrm = new FileInputStream(inFilename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
lineNum = 0;
line = bufRdr.readLine();
while {line != null) {
lineNum++;
processLine(line); //passes line to tokenizer
line = bufRdr.readLine();
}
fileStrm.close();
}
catch (IOException e) {
if (fileStrm != null) {
try { fileStrm.close(); } catch (IOException ex2) { }
}
System.out.println("Error in file processing: " + e.getMessage());
}
}
The lines are passed to this tokenizer method:
private String processLine(String csvRow) {
String thisToken = null;
StringTokenizer strTok;
strTok = new StringTokenizer(csvRow, ",");
while (strTok.hasMoreTokens()) {
thisToken = strTok.nextToken();
}
}
And that's where I get a bit stuck. To initialise my array I think I'd need a for loop, something like
for (int i=0; i<=array.length;i++)
{
array[i].name = readFile("filename.csv");
array[i].manufacturer = readFile("filename.csv");
}
But obviously this will not work. Can anyone suggest how I can go about this? I'd prefer to keep the code mostly intact and figure out a solution using the existing code.
Thanks
First thing: -
You are calling processLine(line);, but are not returning the token read from this method.. So, the token obtained in this method in engulped there only.. So, you should return something from that method..
Second:-
array[i].name = readFile("filename.csv");
array[i].manufacturer = readFile("filename.csv");
In the above code, you are calling readFile() each time for the two attributes.. So, even if you return somthing, these two attributes will be initialized to same value.. Because each time you are starting reading file from scratch..
Third thing: -
In fact your above code will not compile.. Because you are assigning the value of readFile() (which is actually not returning anything) to array.. So give a return type to this method.. It would be String.. And returning the tokens read..
EDIT: -
* I would suggest, you can use split() method of String class.. Tokenizer is not needed here, for justsplittingaround a singlecomma(,)`
Also, rather than using an array, you can use ArrayList, in which you can add your newly created object on the fly.. That way, you will not have to fix the size of array.. (And this is what you will want, as you don't know how much line you will have in your file right?)
Here's what you can do: -
Call the method readFile from somewhere, probably main()
readFile("filename.csv")
In your readFile() method, you can iterate over file to create an ArrayList like this: -
List<Can> yourList = new ArrayList<>();
while ((line = reader.readLine()) != null) {
String[] wordRead = line.split(',');
yourList.add(new Can(wordRead[0], wordRead[1]));
}
I assume, Can is the name of your class as you stated in your problem..

Categories

Resources