Splitting and saving data in Java - java

I'm trying to read a data file and save the different variables into an array list.
The format of the data file looks a little like this like this
5003639MATH131410591
5003639CHEM434111644
5003639PSYC230110701
Working around the bad formatting of the data file, I added commas to the different sections to make a split work. The new text file created looks something like this
5,003639,MATH,1314,10591
5,003639,CHEM,4341,11644
5,003639,PSYC,2301,10701
After creating said file, I tried to save the information into an array list.
The following is the snippet of trying to do this.
FileReader reader3 = new FileReader("example.txt");
BufferedReader br3 = new BufferedReader(reader3);
while ((strLine = br3.readLine())!=null){
String[] splitOut = strLine.split(", ");
if (splitOut.length == 5)
list.add(new Class(splitOut[0], splitOut[1], splitOut[2], splitOut[3], splitOut[4]));
}
br3.close();
System.out.println(list.get(0));
The following is the structure it is trying to save into
public static class Class{
public final String recordCode;
public final String institutionCode;
public final String subject;
public final String courseNum;
public final String sectionNum;
public Class(String rc, String ic, String sub, String cn, String sn){
recordCode = rc;
institutionCode = ic;
subject = sub;
courseNum = cn;
sectionNum = sn;
}
}
At the end I wanted to print out one of the variables to see that it's working but it gives me an IndexOutOfBoundsException. I wanted to know if I'm maybe saving the info incorrectly, or am I perhaps trying to get it to print out incorrectly?

You have a space in your split delimiter specification, but no spaces in your data.
String[] splitOut = strLine.split(", "); // <-- notice the space?
This will result in a splitOut array of only length 1, not 5 like you expect.
Since you only add to the list when you see a length of 5, checking the list for the 0th element at the end will result in checking for the first element of an empty list, hence your exception.

If you expect your data to have a comma or a space separating the characters then you would alter the split line to be:
String[] splitOut = strLine.split("[, ]");
The split takes a regular expression as an argument.
Rather than artificially adding commas I would look at String.substring in order to cut the line you have read into pieces. For example:
while ((strLine = br3.readLine())!=null) {
if (strLine.length() != 20)
throw new BadLineException("line length is not valid");
list.add(new Class(strLine.substring(0,1), strLine.substring(1,7), strLine.substring(7,11), strLine.substring(11,15), strLine.substring(15,19)));
}
[ Untested: my numbers might be out because I a bit knacked, but you get the idea ]

Related

Regex to match a String with asterisk

I'm coding in Java and I want to split my string. I want to split it at.
/* sort */
Yes I plan to split a .java file that I have read as a string so I need it to include "/* sort */". I'm creating a code that sorts Arrays that are predefined in java class file.
Exactly that and do another split at
}
and then I wanted help how to go about splitting up the array since I'll be left with
an example would be this
final static String[] ANIMALS = new String[] /* sort */ { "eland", "antelope", "hippopotamus"};
My goal would be to sort that Array inside a .java file and replace it. This is my current code
private void editFile() throws IOException {
//Loads the whole Text or java file into a String
try (BufferedReader br = new BufferedReader(new FileReader(fileChoice()))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
everything = sb.toString();
}
arrayCutOff = everything.split("////* sort *////");
for(int i = 0; i < arrayCutOff.length; i++){
System.out.println(arrayCutOff[i]);
}
}
This basically reads the whole .txt or .java file completely with the exact same formatting into one string. I planned to split it at /* sort */ and sort the array inside but I realized if I did that I probably can't replace it.
Considered your're using java 8 you might go this direction:
private void editFile() throws IOException {
List<String> lines = Files.readAllLines(Paths.get(fileChoice()));
String content = lines.stream().collect(Collectors.joining(System.lineSeparator()));
Stream.of(content.split(Pattern.quote("/* sort */"))).forEach(System.out::println);
}
However, the trick you're asking for is Pattern.quote, which dates back Java 5. It'll qoute a literal so it can be used as a literal in regExs and is a bit more convenient (and reliable I think) than wrestling around with backslashes...

JAVA: How to convert String ArrayList to Integer Arraylist?

My question is -
how to convert a String ArrayList to an Integer ArrayList?
I have numbers with ° behind them EX: 352°. If I put those into an Integer ArrayList, it won't recognize the numbers. To solve this, I put them into a String ArrayList and then they are recognized.
I want to convert that String Arraylist back to an Integer Arraylist. So how would I achieve that?
This is my code I have so far. I want to convert ArrayString to an Int Arraylist.
// Read text in txt file.
Scanner ReadFile = new Scanner(new File("F:\\test.txt"));
// Creates an arraylist named ArrayString
ArrayList<String> ArrayString = new ArrayList<String>();
// This will add the text of the txt file to the arraylist.
while (ReadFile.hasNextLine()) {
ArrayString.add(ReadFile.nextLine());
}
ReadFile.close();
// Displays the arraystring.
System.out.println(ArrayString);
Thanks in advance
Diego
PS: Sorry if I am not completely clear, but English isn't my main language. Also I am pretty new to Java.
You can replace any character you want to ignore (in this case °) using String.replaceAll:
"somestring°".replaceAll("°",""); // gives "sometring"
Or you could remove the last character using String.substring:
"somestring°".substring(0, "somestring".length() - 1); // gives "somestring"
One of those should work for your case.
Now all that's left is to parse the input on-the-fly using Integer.parseInt:
ArrayList<Integer> arrayInts = new ArrayList<Integer>();
while (ReadFile.hasNextLine()) {
String input = ReadFile.nextLine();
try {
// try and parse a number from the input. Removes trailing `°`
arrayInts.add(Integer.parseInt(input.replaceAll("°","")));
} catch (NumberFormatException nfe){
System.err.println("'" + input + "' is not a number!");
}
}
You can add your own handling to the case where the input is not an actual number.
For a more lenient parsing process, you might consider using a regular expression.
Note: The following code is using Java 7 features (try-with-resources and diamond operator) to simplify the code while illustrating good coding practices (closing the Scanner). It also uses common naming convention of variables starting with lower-case, but you may of course use any convention you want).
This code is using an inline string instead of a file for two reasons: It shows that data being processed, and it can run as-is for testing.
public static void main(String[] args) {
String testdata = "55°\r\n" +
"bad line with no number\r\n" +
"Two numbers: 123 $78\r\n";
ArrayList<Integer> arrayInt = new ArrayList<>();
try (Scanner readFile = new Scanner(testdata)) {
Pattern digitsPattern = Pattern.compile("(\\d+)");
while (readFile.hasNextLine()) {
Matcher m = digitsPattern.matcher(readFile.nextLine());
while (m.find())
arrayInt.add(Integer.valueOf(m.group(1)));
}
}
System.out.println(arrayInt);
}
This will print:
[55, 123, 78]
You would have to create a new instance of an ArrayList typed with the Integer wrapper class and give it the same size buffer as the String list:
List<Integer> myList = new ArrayList<>(ArrayString.size());
And then iterate through Arraystring assigning the values over from one to the other by using a parsing method in the wrapper class
for (int i = 0; i < ArrayString.size(); i++) {
myList.add(Integer.parseInt(ArrayString.get(i)));
}

Analyse large String using processing

I have a String which I need to split and add to different arrays.
This is my String
{"locations":[{"latitude":"1.3846519","longitude":"103.763276","startTime":"1422720220292","duration":"0","accuracy":"50.981998443604"},{"latitude":"1.3845814","longitude":"103.7634384","startTime":"1422720520181","duration":"0","accuracy":"55.532001495361"},{"latitude":"1.3844195","longitude":"103.763209","startTime":"1422720820265","duration":"0","accuracy":"34.5"},{"latitude":"1.3844051","longitude":"103.7632272","startTime":"1422721120466","duration":"0","accuracy":"36"},
],"success":1}
The output I want is like this in different arrays.
latitudeArray[] = // String array of latitude values
longitudeArray[] = // String array of longitude values
startTimeArray[] = // String array of start time values
durationArray[] = // String array of duration values
accuracyArray[] = // String array of accuracy values
I am using processing IDE to analyse my data and I tried matchAll() and split() functions but couldn't get it work.
Could you please help me in getting my output? Thanks.
Edit: I managed to extract one latitude value but my method seems very inefficient. How can I do this inside a loop?
String[] locationData = loadStrings("sample.txt");
ArrayList<String> latitudeArray = new ArrayList<String>();
ArrayList<String> longitudeArray = new ArrayList<String>();
ArrayList<String> startTimeArray = new ArrayList<String>();
ArrayList<String> durationArray = new ArrayList<String>();
ArrayList<String> accuracyArray = new ArrayList<String>();
String temp;
int index;
index = locationData[0].indexOf("latitude");
println(index);
temp = locationData[0].substring(index+11);
println(temp);
index = temp.indexOf(",");
println(index);
latitudeArray.add(temp.substring(0,(index-1)));
println(latitudeArray.get(0));
Wasn't sure in what format the loadStrings() method returns, so I just used the initial String you provided.
You're heading in the right direction with the string methods. This code tries to benefit from the single input string. If you split on "latitude", then all the elemets in the array, except for the first one, will have the numbers we're interested on in the begining. E.g.: split("latitude\":\"") gives all the latitudes in the begining:
[0] = {"locations":[{"
[1] = 1.3846519","longitude":"103.763276","startTime":"1422720220292","duration":"0","accuracy":"50.981998443604"},{"
[2] = 1.3845814","longitude":"103.7634384","startTime":"1422720520181","duration":"0","accuracy":"55.532001495361"},{"
[3] = 1.3844195","longitude":"103.763209","startTime":"1422720820265","duration":"0","accuracy":"34.5"},{"
[4] = 1.3844051","longitude":"103.7632272","startTime":"1422721120466","duration":"0","accuracy":"36"}, ],"success":1}
To read the actual numbers, we just need to read until the next quote("). Doing indexOf("\"") will give use the position till which we must read to retrieve that number. So, just perform a substring(0,indexOfQuote) on it to get the value. The repeat again, but this time splitting on "longitude" to get them.
Full program:
public static void main(String[] args) {
final String INPUT = "{\"locations\":["
+ "{\"latitude\":\"1.3846519\",\"longitude\":\"103.763276\",\"startTime\":\"1422720220292\",\"duration\":\"0\",\"accuracy\":\"50.981998443604\"},"
+ "{\"latitude\":\"1.3845814\",\"longitude\":\"103.7634384\",\"startTime\":\"1422720520181\",\"duration\":\"0\",\"accuracy\":\"55.532001495361\"},"
+ "{\"latitude\":\"1.3844195\",\"longitude\":\"103.763209\",\"startTime\":\"1422720820265\",\"duration\":\"0\",\"accuracy\":\"34.5\"},"
+ "{\"latitude\":\"1.3844051\",\"longitude\":\"103.7632272\",\"startTime\":\"1422721120466\",\"duration\":\"0\",\"accuracy\":\"36\"},"
+ " ],\"success\":1}";
String latitudeArray[] = splitAndCollect("latitude", INPUT);
String longitudeArray[] = splitAndCollect("longitude", INPUT);
String startTimeArray[] = splitAndCollect("startTime", INPUT);
String durationArray[] = splitAndCollect("duration", INPUT);
String accuracyArray[] = splitAndCollect("accuracy", INPUT);
System.out.println("Done");
}
private static String[] splitAndCollect(String string, String input) {
final String COLON = "\":\"";
String[] split = input.split(string + COLON);
String[] output = new String[split.length - 1];
for (int i = 0; i < output.length; i++)
// Using [i+1] - since split[0] contains "locations".
// Subsequent splits will have the numbers needed.
output[i] = split[i + 1].substring(0, split[i + 1].indexOf("\""));
System.out.println(string + "\n" + Arrays.toString(output));
return output;
}
If you can preprocess the file to csv. file using simple shell script, then do string processing in java, I think you can get better performance. For csv. file processing in Java, refer http://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/ (This blog contains simple sample).
If you do some preprocessing step (even in Java) before parsing, you can get all the values to those string arrays simply with one loop. You can use method suggested by Vineet using single loop. So with preprocessing step overall loop count becomes 2.
Thanks,
Mili
It seems that you have data in JSON format. The way you are trying to get data from the is quite difficult (but doable). You can try JSON parser . Its easy to learn and use. You can find one example here.

Empty array after reading text file

It's fixed! Thanks to Edgar Boda.
I created a class that should read a text file and put that into an array:
private static String[] parts;
public static void Start() throws IOException{
InputStream instream = new FileInputStream("Storyline.txt");
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
int numberOfLines=0, numberOfActions;
String line = null, input="";
while((line=buffreader.readLine())!=null){
line=buffreader.readLine();
input+=line;
}
parts=input.split(";");
}
But, when I try and output the array, it only contains one string. The last from the file, that I put in.
Here's the file I read from:
0;0;
Hello!;
Welcome!To this.;
56;56;
So;
I think it's something in the loop; but trying to put parts[number] in there doesn't work... Any suggestions?
You want to read the whole file into an String first maybe:
String line = null;
String input = "";
while((line=buffreader.readLine())!=null){
input += line;
}
parts = input.split(";");
You are overwriting the string array parts in every iteration of your while loop, so that's why it only contains the last line.
To store the entire file contents, with fields split, you'll need a 2-dimensional array, not a 1-dimensional array. Assuming there are 5 lines in the file:
private static String[][] parts = new String[5][];
Then assign each split array to an element of parts each loop:
parts[i++]=line.split(";"); // Assuming you define "i" for the line number
Also, split by default discards trailing empty tokens. To retain them, use the two-arg overload of split that takes a limit parameter. Pass a negative number to retain all tokens.
parts[i++] = line.split(";", -1);
It will only contain the last line; you are reassigning parts every time:
parts = line.split(";");
This trashes the previous reference and reassigns a reference to a new array to it. A better way might be to use a StringBuilder and append the lines and then split later:
StringBuilder stringBuilder = new StringBuilder();
while((line=buffreader.readLine())!=null){
stringBuilder.append(line);
}
parts = stringBuilder.toString().split(";");
This way you will get everything you want in one array. If you want to split everything such that you have one array per line, you will need parts to be a two-dimensional array. But the drawback is that you will need to know how many lines will be there in the file. Instead, you can use List<String[]> to keep track of your arrays:
List<String[]> lineParts = new ArrayList<String[]>();
while((line=buffreader.readLine())!=null){
lineParts.add(line.split(";"));
}

Split a string in Java and picking up a part of it

Say I got a string from a text file like
"Yes ABC 123
Yes DEF 456
Yes GHI 789"
I use this code to split the string by whitespace.
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
String[] tokens = stuff.split(" ");
for (String s : tokens)
System.out.println(s);
}
But I also want to assign Yes to a boolean, ABC to another string, 123 to a int.
How can I pick them up separately? Thank you!
boolean b=tokens[0].equalsIgnoreCase("yes");
String name=tokens[1];
int i=Integer.parseInt(tokens[2]);
Could you clarify what the exact purpose of what you're doing is? You can refer to the separate Strings with tokens[i] with i being the index. You could throw these into a switch statement (since Java 7) and match for the words you're looking for. Then you can take further action, i.e. convert the Strings to Booleans or Ints.
You should consider checking the input to be valid too even if you are expecting the file to always have those 3 words separated by a space.
Create Class Line and List<Line> that will store all your file into list:
public class Line{
private boolean mFlag = false;
private int mNum = 0;
private String mStr;
public Line(String stuff) {
String[] tokens = stuff.split("[ ]+");
if(tokens.length ==3){
mFlag=tokens[0].equalsIgnoreCase("yes");
mNum=Integer.parseInt(tokens[1]);
mStr=tokens[3];
}
}
}
and call it:
public static void main(String[] args) {
List<Line> list = new ArrayList<Line>();
Line line;
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
line = new Line(stuff);
list.add(line);
}
}
If your input String is going to be in the same format always i.e. boolean,String ,int then you can access the individual indices of token array and convert them to your specified format
boolean opinion = tokens[0].equalsIgnoreCase("yes");
String temp = token[1];
int i = Integer.parseInt(token[2])
But you might require to create an array or something that stores the values for consecutive inputs that user does otherwise these variables would be over ridden for every new input from user.

Categories

Resources