[ https://issues.apache.org/jira/browse/LANG-810?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13411325#comment-13411325 ]
Krzysztof Nazarewski edited comment on LANG-810 at 7/11/12 9:17 AM: -------------------------------------------------------------------- Basically {{endIndex}} takes values from 1 to array.length instead of from 0 to {{(array.length - 1)}} In current state {{endIndex}} is "1-based index", not "0-based index" while Java language uses 0-based indexes, also previous argument {{startIndex}} is 0-based. If you put valid endIndex 0, the for loop won't run at all as it checks (i < endIndex) like it was array's length. Let's say you have 1 element array to join (it does not make practical sense, bu should work), it has index 0 and does not have anything beyond 0 index. According to JavaDoc only possible combination of startIndex and endIndex would be (0,0). {{StringUtils.java, line 3394: for (int i = startIndex; i < endIndex; i++) {}} However for loop will not execute even single time because {{(i = startIndex = 0)}} is not lower than {{(endIndex = 0)}}, it is equal to endIndex and the result of joining single element array from it's only index 0 to index 0 will be empty string. Therefore to join that one-element array you need to use combination {{(startIndex = 0, endIndex = 1)}}, where {{(endIndex == array.length)}} is error according to JavaDoc: "endIndex - the index to stop joining from (exclusive). *It is an error to pass in an end index past the end of the array*" Let's make some examples: {code:title="test.java"} import org.apache.commons.lang3.StringUtils; public class Test { public static void main(String[] args) { String[] array = new String[] { "0", "1", "2", "3" }; // 4-element // array, which // has indexes // from 0 to 3 int startIndex = 0; int endIndex = 0; String str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); startIndex = 0; endIndex = 1; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); startIndex = 1; endIndex = 1; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); startIndex = 2; endIndex = 2; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); startIndex = 0; endIndex = 3; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); startIndex = 0; endIndex = 4; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("StringUtils.join(array, \",\", " + startIndex + ", " + endIndex + "); array[" + startIndex + "] == " + array[startIndex] + " array[" + endIndex + "] == " + array[endIndex] + "\n" + str); // index // beyond // boundaries // of // array } } {code} Run it and tell me what is wrong. was (Author: drag0nius): Basically {{endIndex}} takes values from 1 to array.length instead of from 0 to {{(array.length - 1)}} In current state {{endIndex}} is "1-based index", not "0-based index" while Java language uses 0-based indexes, also previous argument {{startIndex}} is 0-based. If you put valid endIndex 0, the for loop won't run at all as it checks (i < endIndex) like it was array's length. Let's say you have 1 element array to join (it does not make practical sense, bu should work), it has index 0 and does not have anything beyond 0 index. According to JavaDoc only possible combination of startIndex and endIndex would be (0,0). {{StringUtils.java, line 3394: for (int i = startIndex; i < endIndex; i++) {}} However for loop will not execute even single time because {{(i = startIndex = 0)}} is not lower than {{(endIndex = 0)}}, it is equal to endIndex and the result of joining single element array from it's only index 0 to index 0 will be empty string. Therefore to join that one-element array you need to use combination {{(startIndex = 0, endIndex = 1)}}, where {{(endIndex == array.length)}} is error according to JavaDoc: "endIndex - the index to stop joining from (exclusive). *It is an error to pass in an end index past the end of the array*" Let's make some examples: {code:title="test.java"} import org.apache.commons.lang3.StringUtils; public class Test { public static void main(String[] args) { String[] array = new String[] {"0", "1", "2", "3"}; // 4-element array, which has indexes from 0 to 3 int startIndex = 0; int endIndex = 0; String str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("1: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); startIndex = 0; endIndex = 1; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("2: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); startIndex = 1; endIndex = 1; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("3: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); startIndex = 2; endIndex = 2; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("4: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); startIndex = 0; endIndex = 3; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("5: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); startIndex = 0; endIndex = 4; str = StringUtils.join(array, ",", startIndex, endIndex); System.out.println("6: " + str + "\n\tarray[" + startIndex + "] == " + array[startIndex] + "\tarray[" + endIndex + "] == " + array[endIndex]); // index beyond boundaries of array } } {code} will output: {code} 1: array[0] == 0 array[0] == 0 2: 0,1 array[0] == 0 array[1] == 1 3: array[1] == 1 array[1] == 1 4: array[2] == 2 array[2] == 2 5: 0,1,2,3 array[0] == 0 array[3] == 3 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 at org.apache.commons.lang3.StringUtils.join(StringUtils.java:3398) at Test.main(Test.java:28) {code} > StringUtils.join() endIndex, bugged for loop > -------------------------------------------- > > Key: LANG-810 > URL: https://issues.apache.org/jira/browse/LANG-810 > Project: Commons Lang > Issue Type: Bug > Components: lang.* > Affects Versions: 3.1 > Reporter: Krzysztof Nazarewski > Assignee: Joerg Schaible > Original Estimate: 1m > Remaining Estimate: 1m > > endIndex is described as index, but for loop still checks it as "array > length". > Basically missing equal sign > commons-lang3-3.1-sources.jar, StringUtils.java lines 3309, 3394: > for (int i = startIndex; i < endIndex; i++) { > should be: > for (int i = startIndex; i <= endIndex; i++) { -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa For more information on JIRA, see: http://www.atlassian.com/software/jira