Java empty String split ArrayIndexOutOfBoundsException [duplicate] - java

This question already has answers here:
Java String split is not working
(3 answers)
Closed 7 years ago.
I have come across an unexpected feature in the split function of String in Java, here is my code:
final String line = "####";
final String[] lineData = line.split("#");
System.out.println("data: " + lineData[0] + " -- " + lineData[1]);
This code gives me an ArrayIndexOutOfBoundsException, whereas I would expect it to print "" and "" (two empty Strings), or maybe null and null (two null Strings).
If I change my code for
final String line = " # # # #";
final String[] lineData = line.split("#");
System.out.println("data: " + lineData[0] + " -- " + lineData[1]);
Then it prints " " and " " (the expected behaviour).
How can I make my first code not throwing an exception, and giving me an array of empty Strings?
Thanks

You can use the limit attribute of split method to achieve this. Try
final String line = "####";
final String[] lineData = line.split("#", -1);
System.out.println("Array length : " + lineData.length);
System.out.println("data: " + lineData[0] + " -- " + lineData[1]);

As always, answer is written in the Javadoc
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
Since your array is composed only by empty strings, they are not added to it, thus trying to access the values result in an ArrayOutOfBoundException.

If I understand your question, this would do it -
final String line = " # ";
final String[] lineData = line.split("#");
System.out.println("data: " + lineData[0] + " -- " + lineData[1]);
The problem is that the empty string isn't a character.

Related

String index out of range: -5 [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have a problem when i test runQuery, the problem is String index out of range: -5 and i can't find the solution
#Test
void testRunQuery() throws FileNotFoundException, IOException, InterruptedException {
final Answer answer = new Answer();
String[] args = new String[5];
final String year = "yyyy ";
final String month = "mm ";
final String day = "dd ";
final String limit = "limit ";
args[0] = year.substring(5);
args[1] = month.substring(3);
args[2] = day.substring(3);
args[3] = null;
args[4] = limit.substring(6);
Job result = answer.runQuery(args);
assertNotNull(result);
}
And this is runQuery where i make the query
public Job runQuery(final String[] args) throws InterruptedException {
// Use standard SQL syntax for queries.
// See: https://cloud.google.com/bigquery/sql-reference/
// Variabili per le query
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
mm=Integer.valueOf(args[ONE].substring(THREE)),
dd=Integer.valueOf(args[TWO].substring(THREE)),
limit=Integer.valueOf(args[FOUR].substring(SIX));
final QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(
"SELECT DISTINCT owner_user_id "
+ "FROM `bigquery-public-data.stackoverflow.posts_answers` "
+ "WHERE extract(year from creation_date) = #yyyy "
+ "AND extract(month from creation_date) = #mm "
+ "AND extract(day from creation_date) = #dd "
+ "AND owner_user_id is not null "
+ "AND owner_user_id > 0 "
+ "ORDER BY owner_user_id ASC LIMIT #limit ")
.addNamedParameter("yyyy", QueryParameterValue.int64(yyyy))
.addNamedParameter("mm", QueryParameterValue.int64(mm))
.addNamedParameter("dd", QueryParameterValue.int64(dd))
.addNamedParameter("limit", QueryParameterValue.int64(limit))
.setUseLegacySql(false).build();
// Create a job ID so that we can safely retry.
final JobId jobId = JobId.of(UUID.randomUUID().toString());
Job queryJob=bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
// Wait for the query to complete.
queryJob = queryJob.waitFor();
// Check for errors
if (queryJob == null) {
throw new RuntimeException("Job no longer exists");
} else if (queryJob.getStatus().getError() != null) {
// You can also look at queryJob.getStatus().getExecutionErrors() for all
// errors, not just the latest one.
throw new RuntimeException(queryJob.getStatus().getError().toString());
}
return queryJob;
}
String index out of range: -5 at the line 93 of runQuery; this is the line:
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE))
You have misunderstood what argument Java's String.substring function takes.
In short, you appear to think the argument takes the length of the substring. It doesn't - rather, it specifies the "begin-index" - ie. where in the supplied string to start copying.
So when you say :
final String year = "yyyy ";
args[0] = year.substring(5);
you are NOT actually setting args[0] to a 5-character string. In stead, you are setting it to the part of string "yyyy " starting at position 5 - in other words, you are setting it to empty-string.
So when you subsequently say
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
and assuming you have ZERO set to 0 and FIVE to 5, this will fail since you have args[0] as empty-string "", and you can't get a substring starting at position 5 from "".
To sum up, if you have
String myString = "smiles";
System.out.println("substring(0, 4) = <" + myString.substring(0, 4) + ">");
System.out.println("substring(2, 4) = <" + myString.substring(2, 4) + ">");
System.out.println("substring(4) = <" + myString.substring(4) + ">");
the output will be :
substring(0, 4) = <smil>
substring(2, 4) = <il>
substring(4) = <es>
In short, get rid of your ".substring" calls in both your test and your main code.
Check out the spec at https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int)
You first define a variable
final String year = "yyyy ";
then you use subString
args[0] = year.substring(5);
args[0] is now a String value of nothing( args[0] equals "")
then you are trying to subString it again.
final Integer yyyy=Integer.valueOf(args[ZERO].substring(FIVE)),
this won't work because args[0] is an empty String.
You should only use substring once, either inside the function or before calling the function.

How to remove specific line from multi-line string

I have below java string as command output
String output = "NIC Value\n"
+ "------ -----\n"
+ "vmn0 on \n"
+ "vmn1 on \n"
+ "vmn2 on \n"
+ "vmn3 on \n"
+ "vmn4 on";
I want to remove second line with dash from above string. How can I do it?
I tried it using contains method but it is generating blank line after removing second line.
if(output!=null && output.contains("-"))
output = output.replace("-","");
This is complete answer you are looking for:
String output = "NIC Value\n"
+ "------ -----\n"
+ "vmn0 on \n"
+ "vmn1 on \n"
+ "vmn2 on \n"
+ "vmn3 on \n"
+ "vmn4 on";
String str = Stream.of(output.split("\n"))
.filter(s -> !s.contains("--"))
.collect(Collectors.joining("\n"));
You can use this to remove that line and use the result,
String result = output.replace("------ -----\n", "");
It will replace that line with an empty String

Splitting array in string does not give last element

Hi I am splitting and storing string with use of array but does not give result
String str = "123456";
String[] arrOfStr = str.split("");
String otpnum1 = arrOfStr[0];
String otpnum2 = arrOfStr[1];
String otpnum3 = arrOfStr[2];
String otpnum4 = arrOfStr[3];
String otpnum5 = arrOfStr[4];
String otpnum6 = arrOfStr[5];
System.out.println("otp"+otpnum1+otpnum2+otpnum3+otpnum4+otpnum5+otpnum6);
OUTPUT
System.out: otp12345
You are printing without any space or newline, which is the reason you are not able to interpret individual variables. Use this
System.out.println("otp " + otpnum1+ " " + otpnum2+" " + " "+ otpnum3+ " " + otpnum4+ " " + otpnum5+ " " + otpnum6);
I understand, the output is 12345, and expected 123456 for the result.
But, looking your code looks like correct.
I have try your code here, for test, and works fine.
The output was: otp123456

Java string split gives array index out of bounds error

I came across this unusual error today. Can anyone explain me what I am doing wrong. Below is the code:
AreStringsPermuted checkStringPerObj = new AreStringsPermuted();
String[] inputStrings = {"siddu$isdud", "siddu$siddarth", "siddu$sidde"};
for(String inputString : inputStrings){
String[] stringArray = inputString.split("$");
if(checkStringPerObj.areStringsPermuted(stringArray[0],stringArray[1]))
System.out.println("Strings : " + stringArray[0] + " ," + stringArray[1] + " are permuted");
else
System.out.println("Strings : " + stringArray[0] + " ," + stringArray[1] + " are not permuted");
}
The above code errors out at when i try to split the string. For some reason split does not work when I try to divide each string using "$". Can any one explain me what I am doing wrong here?
Below is the error message:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at arraysAndStrings.TestClass.checkStringsPermuted(TestClass.java:24)
at arraysAndStrings.TestClass.main(TestClass.java:43)
String.split() takes a regular expression, so you need to quote strings that contain characters that have special meanings in regular expressions.
String regularExpression = Pattern.quote("$");
for (String inputString : inputStrings) {
String[] stringArray = inputString.split(regularExpression);
String.split( ) uses regex partern and $ has special meaning in regex(the end of line).
In your case, use "\$" instead of "$".
String []arrayString = inputString.split("\\$");
For more information,
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

.split("|") doesn't return the correct string [duplicate]

This question already has answers here:
Splitting a Java String by the pipe symbol using split("|")
(7 answers)
Closed 7 years ago.
I'm sending this string from the client to the server:
Ar|0.04107356|-0.31299785|-0.9991561
That string is as printed out by the server - So it is correct.
"Ar" is the packet name, and the values are the velocity of an arrow that the archer is going to shoot.
So to get those values, I'm using
String[] values = str.split("|");
And then
a.shoot(Float.valueOf(values[1]), Float.valueOf(values[2]), Float.valueOf(values[3])); //a is an archer
The problem is, values1, values[2], and values[3] seem to be corrupt or unrecognizable.
My full code is this:
public void handleMessage(String str){
System.out.println(str);
String[] values = str.split("|");
if (values[0].contains("Ar")){
System.out.println("X: " + values[1] + " Y: " + values[2] + " Z: " + values[3]);
}
System.out.println("Vals: " + values[0] + " " + values[1] + " " + values[2] + " " + values[3]);
if (true) return; //Returning so I can analyze de-bug messages without crashes.
for (Archer a : GameServer.archers){
a.shoot(Float.valueOf(values[1]), Float.valueOf(values[2]), Float.valueOf(values[3]));
}
When I print out the "Vals" message, it comes out like this:
Vals: A r |
What is going wrong here?
The horizontal bar has a special meaning in Java regular expressions which you must escape in order to use as a literal:
String[] values = str.split("\\|");

Categories