How to solve java.lang.ArrayIndexOutOfBoundsException error - java

I am trying to read users id and their link type from a txt file. The data is given in following format.
SRC:aa
TGT:bb
VOT:1
SRC:cc
TGT:bb
VOT:-1
where 'SRC' and 'TGT' indicators of the users id. In data, some users ids are blank, i.e. users disagree to reveal their identities as following:
SRC:
TGT:cc
VOT:-1
SRC:ff
TGT:bb
VOT:1
In this case, I want to give them a special id, "anonymous". So, I wrote the following code:
//Reading source
dataline = s.nextLine();
String[] line1parts = new String[2];
.
.
//split the line at ":"
line1parts = dataline.split(":");
//if the line has source
if (line1parts[0].trim().equals("SRC")){
//if the soruce name is empty
if (line1parts[1].isEmpty()) {
src = "anonymous";
System.out.print("src: " + src);
}
//if the source already integer id
else {
src = line1parts[1].trim();
System.out.print("src: " + src);
}
}
The program shows java.lang.ArrayIndexOutOfBoundsException error. I have also tried if (line1parts[1].equals("") and if (line1parts[1].equals(null). Probably for the case SRC: (when empty) the string array is not creating any object (sorry if I am wrong. I am very new in java). How can I assign an user ID when it is empty? Thanks in advance.

If a line only contains SRC: the line1parts array will have only one item, thus line1parts[1] raises an ArrayIndexOutOfBoundsException .
Replace if (line1parts[1].isEmpty()) by if (line1parts.length < 2 )

Has StephaneM made me remember, the split method trim the empty cell during the splitting. This removed every empty cells at the end. This mean the empty cell if there is no SRC value in your case
To prevent this, you can call
java.lang.String.split(String, int)
This integer specify the length of the array you want, at minimum.
line1parts = dataline.split(":", 2);
You are sure to receive an array with length of 2 or more. So this could still remove some cells, but with a length constraint.
A good think to know is that if you send -1, the split will return EVERY cells. No trimming is done.

You are trying to get the index which is not present.
split() helps to divide value from regex you provided.
you are split the string
1."TGT:cc" in this case split method split String value from ":" and it is returning an array of size 2 i.e. [TGT,cc] (it has 0 and 1 index).
2.When you split the String "SRC:" in this case split method create an array of size 1 i.e [SRC] (it has only 0 index) because in this String after ":" nothing and so that it does not create extra index for null value.
When you call "line1parts[1].isEmpty()" it throw ArrayIndexOutOfBoundsException because it does not have the index 1.
Here you have to check "line1parts.length" before call "line1parts[1].isEmpty()".
line1parts = dataline.split(":");
// if the line has source
if (line1parts[0].trim().equals("SRC")) {
if (line1parts.length > 1) {
// if the soruce name is empty
if (line1parts[1].isEmpty()) {
src = "anonymous";
System.out.print("src: " + src);
}
// if the source already integer id
else {
src = line1parts[1].trim();
System.out.print("src: " + src);
}
}
}
Or-----------------
You have to do ::
line1parts = dataline.split(":",2);

Related

How to find if an array index Exists?

Basically I need to check if a String contains 2 indexes.
Based on my googling I found that I could Either use part[0].length() > 0 || part[0] != null But none happen to help me here.
My code:
String[] parts = datareceived.split("&");
if(!(parts[0].length()>0) && parts[0] == null){
out.print("String is null");
return;
}
if(!(parts[1].length()>0) && parts[1] == null){
out.print("String is null");
return;
}
But here in parts[1] i'm getting an exception which says:
java.lang.ArrayIndexOutOfBoundsException: 1
at pack.reg.pack.serv.doPost(serv.java:10)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
Thanks in advance!
Basically I need to check if a String contains 2 indexes
If you are using split() it returns you an array which you can use .length to check the size of the returned tokens:
if(parts.length >= 2)
But that is not gonna tell if the second index is empty, right?
If you are afraid of getting empty string, you can trim() the String first:
String[] parts = datareceived.trim().split("&");
It means split returning an array of string and its size is 1. Thats why you are getting java.lang.ArrayIndexOutOfBoundsException
and if you want to check whether array size is 2 you can do following
part.length >= 2
// write your logic here
When you're getting an ArrayIndexOutOfBoundsException when calling parts[1], but not when calling parts[0], we can conclude that parts.length == 1. Hence, since indices start at 0, index 0 contains the whole string, and index 1 in the split array (and up) doesn't exist.
--> Problem found: Your datareceived doesn't contain a &, hence it won't be split anywhere.
Solution: Hoping I understood your problem correctly (checking whether a string datareceived contains a value at certain indices), I wrote you a piece of code that should work.
String datareceived = "01234";
int index1 = 2;
int index2 = 5;
if (datareceived.length() > index1) {
//the string has a value at index1. With the given example, this if-query would be true.
}
if (datareceived.length() > index2) {
//the string has a value at index2. With the given example, this if-query would be false.
}
Side-note when using .split:
I found that, when using String.split("expression"), the "expression" part can contain regex-codes (regular expression). Therefore, if you're using any symbol that is a valid regex expression (such as . or $), it will not work (at least, not necessarily). For example, in regex, . means "any character", which will essentially give you an empty array.
(Note: I'm no regex expert, but "&" doesn't appear to be a valid regular expression)
Example:
String s = "a,b";
String[] strings = s.split(",");
for (String str : strings) {
System.out.println(str + "_");
}
//will print out "a_b_"
Example (not working as desired):
String s = "a.b";
String[] strings = s.split(".");
//"strings" is an empty array, since "a", ".", and "b" are "any character".
Solution:
instead of .split("."), use .split("\\.")

Copy a string splitted to another string

In some place of a class I have declared a temporal String variable:
String name;
Which I will use to store data from a text. The text have many fields with these two types of format:
Type: text/html
name=foo
For this case, I am particularly interested in the fields of the type name=foo
So, I breaked previously the lines of the text using split
String lines[] = text.split("\n");
And, again, I will use split to identify the fields of the type mentioned. In the code below, the while cycle stops where it detects a name=foo field, and prints the value of that field in the console.
int i = 0; // Counter for the while cycle
while (!(lines[i].split("=")[0].equals("name"))) {
i++;
if (lines[i].split("=")[0].equals("name")) // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1]; // <-- My problem is here
}
My problem starts when I want to copy the value of the field to the String variable mentioned early, giving me an java.lang.ArrayIndexOutOfBoundsException.
I need that String to do something with it later. Any idea to safely copy the value of that field to a String variable?
Adding paranthesis to your if saves you from two problems:
if a line contains no = the whole String is in [0] and accessing [1] will result in said Exception
you are changing (overwriting) the variable name regardless of the condition
To please the compiler you may also want to intialize name to something like null.
int i = 0; // Counter for the while cycle
while (!(lines[i].split("=")[0].equals("name"))) {
i++;
if (lines[i].split("=")[0].equals("name")){ // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1]; // <-- My problem is here
}
}
In your code:
String name;
name = lines[i].split("=")[1];
Here name will overwrite every time.
I think you are looking for something like this:
String names[];
String lines[] = text.split("\n");
names[] = new String[lines.length];
And inside you while loop do it like:
names[i] = lines[i].split("=")[1];
There are quite a few things to note about your code:
you probably miss {} after the if-statement and therefore update name every run of the while-loop
you access [1] without checking how many elements the split("=") yielded
you literally call split("=") 4 times on almost every line. Save CPU-time by introducing a temporary variable!
you can replace your while-loop by a for-loop which also finds name=value in the first line and does not "throw up" if name=value is not inside any of the lines (you don't check whether i is less than lines.length)
I left your comments inside my answer; feel free to remove them.
Variant a (using an index):
for (int i = 0; i < lines.length; i++) {
// Only split once and keep X=Y together in name=X=Y by specifying , 2
final String[] split = lines[i].split("=", 2);
if (split.length == 2 && split[0].equals("name")){ // If the field is name...
System.out.println(split[1]); // Prints the value of the field
name = split[1]; // <-- My problem is here
break; // no need to look any further
}
}
Variant b (using "for-each"):
for (String line : lines) {
// Only split once and keep X=Y together in name=X=Y by specifying , 2
final String[] split = line.split("=", 2);
if (split.length == 2 && split[0].equals("name")) { // If the field is name...
System.out.println(split[1]); // Prints the value of the field
name = split[1]; // <-- My problem is here
break; // no need to look any further
}
}
I suppose your problem is when you reach the last line or a line which doesn't contains a "=" sign. You are checking
!(lines[i].split("=")[0].equals("name"))
but then you add 1 to i, so maybe this condition now is false
if (lines[i].split("=")[0].equals("name"))
and you will get java.lang.ArrayIndexOutOfBoundsException here
name = lines[i].split("=")[1];
if the line doesn't contains a "=".
Try
if (lines[i].split("=")[0].equals("name")) { // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1];
}

Java: Comparing strings

I have an array list named myArraylist that contains items of the class named TStas. Tstas has a string variable named st_name. I want to search the array list, looking for the TStas instance whose st_name is equal to the string look for and when found return the position (found places) of the TStas in the array list.
public static List<Integer> findplace_byname(String lookfor){
List<Integer> foundplaces = new ArrayList<>(); //list to place posistions of found items
for(int k=0; k<myArraylist.size(); k++) {
TStas a=myArraylist.get(k);
JOptionPane.showMessageDialog(null, "#"+a.st_name+"#"+lookfor+ "#"); //just to check if everything is read,
if ((a.st_name).equals(lookfor)){
foundplaces .add(k);
}
}
return foundplaces;
}
My problem is that the code fails to detect the equality when comparing to the a.st_name of the first item in myArraylist.
For example:
if I have in myarrailist an item with a.st_name=S9, an item with a.st_name=K9 and another with a.st_name=G4. When lookfor is K9 or G4 all is ok. When searching for the first item in the array having a.st_name=S9 the code fails to "see" the equality.
I am using the showMessageDialog to check that the variable is realy read and it is so. Also I tried to delete or change the 1st item in the arraylist, but the same problem goes on: The 1rst item is not found.
What is happening here?
EDIT
I used the trim() to remove any possible spaces but nothing changed. I then used .length() on the "trimed" string to get the length of each string to be compared and I found that for some reason the 1st element while being "S9" without any spaces has a length of 3!! Is it possible that some king of character is hidden? (I have no idea, a paragraph character or what?)
There is no issue in your current code, check this code your self.
List<Integer> foundplaces = new ArrayList<>();
List<String> myArraylist=new ArrayList<>();
myArraylist.add("S9");
myArraylist.add("K9");
myArraylist.add("G4");
for(int k=0; k<myArraylist.size(); k++) {
String a=myArraylist.get(k);
JOptionPane.showMessageDialog(null, "#" + a + "#" + "S9" + "#");
if ((a).equals("S9")){
foundplaces .add(k);
System.out.println(k);
}
}
You can see it is working fine. same as your current code.
I found where the problem is.
As I mentioned is a comment I am using a txt file to populate myarraylist . Windows notepad ads automatically to the beginning of text files a BOM character.
(http://en.wikipedia.org/wiki/Byte_Order_Mark.). This character is the problem because I may read "S9" (the first text in the txt file) but it actually is the \65279 character plus "S9".
So using the following when reading the text file that is used to populate myarraylist the problem is solved.
if((int)readingstring.charAt(0)==65279){
readingstring=readingstring.substring(1);
}
Thanks for your help.

Pulling just certain address from href tag in string always ends in .jpg

I have a string that always looks like so:
Site Info
...where sitenum=XXX will be any 3 or 4 or 5 number combo. I am trying to get just the sitenum from this string.
I figured this would give me the correct information for 3 numbers:
String src = de.substring(de.lastIndexOf("sitenum=") + 3);
However, that just takes 'sit' off of the 'sitenum=' and returns everything else like ">Site Info
I would like it to stop after getting the numbers and hitting the " that is found just after the numbers.
Am i using lastIndexOf incorrectly?
EDIT -- Answer worked for one url, but not another:
http://www.wcc.nrcs.usda.gov/cgibin/wygraph-multi.pl?state=NV&wateryear=current&stationidname=19K07S
I am trying to pull 'state' from this url, but it is not pulling state, just replacing letters in 'state'... Here is the code:
String state = de.substring(de.lastIndexOf("state=") + 2,
de.indexOf("&", de.lastIndexOf("state=")));
The state is always a 2 letter or the number 0... When I run this on my string I get:
ate=0
for example... I am confused on how this works?
EDIT EDIT! AH! I get it... so 2 needs to be 6 cause that is the amount of chars I am comparing to find the next char from?
Use this:
String src = de.substring(de.lastIndexOf("sitenum=") + 8,de.indexOf("\"",de.lastIndexOf("sitenum=")));
Not the best way of doing it, but check if it is what you need:
String src = de.substring(de.lastIndexOf("sitenum=") + "sitenum=".length(), de.indexOf(">Site Info") - 1);
Actually you are trying to get the text which is after "sitenum=", but lastIndexOf("sitenum=") will return the starting index of "sitenum=" and not the text which you are expecting
try
int startindex = de.lastIndexOf("sitenum=") + "sitenum=".length();
int endIndex = de.lastIndexOf("\">Site Info</a>");
String src = de.substring(startindex ,endIndex);

OpenCSV returns a string even when there is no value in the CSV row

I'm writing a program to check if the first two rows, excluding the header, contain any data or not. If they do not, the file is to be ignored, and if either of the first two rows contain data, then process the file. I am using OpenCSV to retrieve the header, the first row and the second row into 3 different arrays and then checking them for my requirements. My problem is that even if the first two rows are empty, the reader returns something like [Ljava.lang.String;#13f17c9e as the output of the first and/or second row (depending on my test files).
Why does it return anything at all, other than a null, that is?
I'm not at my computer right now so excuse any mistakes~ The OpenCSV API Javadocs is rather brief but there doesn't seem to be much to it. Reading a line should parse the content into an array of strings. An empty line should result in an empty string array which gives something like [Ljava.lang.String;#13f17c9e if you try to print it out...
I would assume that the following example file:
1 |
2 |
3 | "The above lines are empty", 12345, "foo"
would produce the following if you did myCSVReader.readAll()
// List<String[]> result = myCSVReader.readAll();
0 : []
1 : []
2 : ["The above lines are empty","12345","foo"]
To perform what you describe in your question, test for length instead of some sort of null checking or string comparison.
List<String> lines = myCSVReader.readAll();
// lets print the output of the first three lines
for (int i=0, i<3, i++) {
String[] lineTokens = lines.get(i);
System.out.println("line:" + (i+1) + "\tlength:" + lineTokens.length);
// print each of the tokens
for (String token : lineTokens) {
System.out.println("\ttoken: " + token);
}
}
// only process the file if lines two or three aren't empty
if (lineTokens.get(1).length > 0 || lineTokens.get(2).length > 0) {
System.out.println("Process this file!");
processFile(lineTokens);
}
else {
System.out.println("Skipping...!");
}
// EXPECTED OUTPUT:
// line:1 length:0
// line:2 length:0
// line:3 length:3
// token: The above lines are empty
// token: 12345
// token: foo
// Process this file!

Categories