# Read an input text file and store the tokens in 2 different arrays

I am very new to Java so please ignore if there are obvious mistakes. If my question seems redundant then please guide me towards the correct link. However, I have surfed enough in order to find the answer. Any changes in code will be greatly appreciated.

I am reading an input file and storing the elements of it in a 2D array. What I want to do is split that array in 2 separate arrays. 1st array would contain all the characters which is firstDimension in my code. Now, I want another array which stores all the integers in an array. I just have to print those arrays. This array should be created as soon as the special character > is observed.

This can be done in 2 ways:

1. Read the strings in the file and store all of the elements in a 2D array and then divide the array into 1 double and one 2D char array
2. Read only chars from the file and store it in char array and then read only double values from the file and store it in different array.

My input file has text:

a A b u>0.0001
b b X g>0.0005
Y z N H>0.0003

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Delimiter {
public static void main(String[] args)
{
try {
Scanner scanner = new Scanner(new File("hello.txt"));
scanner.useDelimiter(System.getProperty("line.separator"));
ArrayList<String> list = new ArrayList<String>();
while (scanner.hasNext()) {
}
scanner.close();
// finally convert the arraylist to a char[][]
char[][] firstDimension = new char[list.size()][];
for (int i = 0; i < list.size(); i++) {
firstDimension[i] = list.get(i).toCharArray();
}
for (int i = 0; i < firstDimension.length; i++)
{
for (int j = 0; j < firstDimension[i].length; j++)
{
//System.out.println(firstDimension[i][j]);
System.out.print(" "+firstDimension[i][j]);
System.out.println("");
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

-
Your code does not actually process the double values.... –  rolfl Feb 11 at 0:17
Can you guide me as to how should i parse only the characters and make one array. –  user3293848 Feb 11 at 0:52

A useful first step for you to take is to separate out 1 item of functionality in to a class. Your method should be broken up in to several classes, but you will get the idea with just one.

This one class, call it DataParser for want of a better name, will be used like this:

DataParser parser = new DataParser();
// set up a loop over the input data
for (String line : inputlines) {
parser.parseLine(line)
}
char[][] chars = parser.getChars();
double[] doubles = parser.getDoubles();


Now, about how we read the file. I recommend something simple that's new in Java 7: Files.readAllLines(Path, Charset).

Path inputpath = Paths.get("hello.txt");


OK, we have our input lines that way, and we can string together the two sections:

Path inputpath = Paths.get("hello.txt");

DataParser parser = new DataParser();
// set up a loop over the input data
for (String line : inputlines) {
parser.parseLine(line);
}
char[][] chars = parser.getChars();
double[] doubles = parser.getDoubles();


Now, about that DataParser class.... it should look something like:

public class DataParser {
private final List<char[]> charlist = new ArrayList<>();
private final List<Double> doublelist = new ArrayList<>();

public void parseLine(String line) {
int charpos = line.indexOf('>');
if (charpos >= 0) {
} else {
// the line does not have a >
// throw an exception?
}
}

public char[][] getChars() {
return charlist.toArray(new char[charlist.size()][]);
}

public double[] getDoubles() {
double[] ret = new double[doublelist.size()];
int cnt = 0;
for (Double d : doublelist) {
ret[cnt++] = d;
}
return ret;
}

}


This class will 'accumulate' the parsed data, and return it when asked. It needs to do some tricks with both accumulators to get the data out in the right format, but you should be able to figure it out.

Edit Here, I did it for you:

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DataParser {
private final List<char[]> charlist = new ArrayList<>();
private final List<Double> doublelist = new ArrayList<>();

public void parseLine(String line) {
int charpos = line.indexOf('>');
if (charpos >= 0) {
} else {
// the line does not have a >
// throw an exception?
}
}

public char[][] getChars() {
return charlist.toArray(new char[charlist.size()][]);
}

public double[] getDoubles() {
double[] ret = new double[doublelist.size()];
int cnt = 0;
for (Double d : doublelist) {
ret[cnt++] = d;
}
return ret;
}

public static void main(String[] args) throws IOException {
Path inputpath = Paths.get("hello.txt");

DataParser parser = new DataParser();
// set up a loop over the input data
for (String line : inputlines) {
parser.parseLine(line);
}
char[][] chars = parser.getChars();
double[] doubles = parser.getDoubles();

System.out.println(Arrays.deepToString(chars));
System.out.println(Arrays.toString(doubles));
}

}


Output:

   [[a,  , A,  , b,  , u], [b,  , b,  , X,  , g], [Y,  , z,  , N,  , H]]
[1.0E-4, 5.0E-4, 3.0E-4]

-
Thankyou for such a detailed idea about the implementation. But can you tell me if 'StandardCharSets cannot be resolved to a variable' is the issue, what actually is going wrong. Beacuse of this error 'inputlines' has null values and it is not getting used to create char or double list. –  user3293848 Feb 11 at 17:59
I mis-typed it.... used a capital S by mistake see: the StandardCharsets JavaDoc –  rolfl Feb 11 at 18:00
Now it says "UTF8 cannot be resolved or is not a field" –  user3293848 Feb 11 at 18:21
sorry.got it, it should be UTF_8 –  user3293848 Feb 11 at 18:23
I just typed the code above in to the CodeReview edit box... never tested it, but it should be close to working, but you will/may have to tweak a few things. –  rolfl Feb 11 at 18:34

Assuming that the characters on the left of the ">" are unique (or the doubles to the right are unique), the easiest way I can think of to do this is to use a HashMap object. Just split the string on the ">", and use one of them as the key and one as the value. When you're done, just retrieve the 2 collections with the keySet() and values() methods and then convert them with toArray().

I'd also take a look at the string split() method - makes parsing really easy with a fixed format like this.

Edit:

    HashMap<String, Double> lists = new HashMap<String, Double>();
while (scanner.hasNext())
{
String[] temp = scanner.next().split(">");
lists.put(temp[0], Double.parseDouble(temp[1]));
}

-
Thankyou so much for your input.Since i am storing all the characters in the strig in ArrayList, split method does not work here. –  user3293848 Feb 11 at 2:35
However I will try doing it using hashmap. Thank you. –  user3293848 Feb 11 at 2:35
@user3293848 Welcome to Code Review / Stack Exchange! Please note, the best way to say "Thanks!" on SE, is by voting (and accepting) on the helpful answers :) –  Mat's Mug Feb 11 at 2:43
The .split() function is a good way to process both sides of the ">". If you take each line that you are putting into the ArrayList and call .split(">") on it, element 0 will be the characters and element 1 will be your double. –  Comintern Feb 11 at 2:43
Thankyou for your help.But when I tried splitting the string which(in my code) is stored in 'list'. It says, split method is not defined for ArrayLists. Can you please show me a pseudo code if possible, it would be a great help. –  user3293848 Feb 11 at 2:51