6
\$\begingroup\$

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()) {
                list.add(scanner.next());
            }
            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();
        }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Your code does not actually process the double values.... \$\endgroup\$
    – rolfl
    Commented Feb 11, 2014 at 0:17
  • \$\begingroup\$ Can you guide me as to how should i parse only the characters and make one array. \$\endgroup\$ Commented Feb 11, 2014 at 0:52

2 Answers 2

7
\$\begingroup\$

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();

The advantage of this is that you can separate out your file-reading logic from your parsing logic.

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");
List<String> inputlines = Files.readAllLines(inputpath, StandardCharsets.UTF_8);

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

Path inputpath = Paths.get("hello.txt");
List<String> inputlines = Files.readAllLines(inputpath, StandardCharsets.UTF_8);

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) {
            charlist.add(line.substring(0, charpos).toCharArray());
            doublelist.add(Double.parseDouble(line.substring(charpos + 1)));
        } 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) {
            charlist.add(line.substring(0, charpos).toCharArray());
            doublelist.add(Double.parseDouble(line.substring(charpos + 1)));
        } 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");
        List<String> inputlines = Files.readAllLines(inputpath, StandardCharsets.UTF_8);

        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]
\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Feb 11, 2014 at 17:59
  • \$\begingroup\$ let us continue this discussion in chat \$\endgroup\$ Commented Feb 11, 2014 at 19:44
6
\$\begingroup\$

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]));
    }
\$\endgroup\$
8
  • \$\begingroup\$ Thankyou so much for your input.Since i am storing all the characters in the strig in ArrayList, split method does not work here. \$\endgroup\$ Commented Feb 11, 2014 at 2:35
  • \$\begingroup\$ However I will try doing it using hashmap. Thank you. \$\endgroup\$ Commented Feb 11, 2014 at 2:35
  • 1
    \$\begingroup\$ @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 :) \$\endgroup\$ Commented Feb 11, 2014 at 2:43
  • \$\begingroup\$ 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. \$\endgroup\$
    – Comintern
    Commented Feb 11, 2014 at 2:43
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Feb 11, 2014 at 2:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.