[ 
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:39 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*"

Example code:
{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" };

                printResult(array, 0, 0);
                printResult(array, 0, 1);
                printResult(array, 1, 1);
                printResult(array, 2, 2);
                printResult(array, 0, 3);
                printResult(array, 0, 4);
        }

        public static void printResult(String[] array, int startIndex, int 
endIndex) {
                String str = StringUtils.join(array, " ", startIndex, endIndex);
                System.out.println("Running:\tStringUtils.join(array, \",\", " 
+ startIndex + " " + endIndex + ");");
                System.out.println("Result: \t" + str);
                System.out.println("array[" + startIndex + "]:\t'" + 
array[startIndex] + '\'');
                System.out.println("array[" + endIndex + "]:\t'" + 
array[endIndex] + '\'');
                System.out.println();
        }
}
{code}

Now tell me what is wrong with the code, because result is:
{code}
Running:        StringUtils.join(array, " ", 0, 1);
Result:         
array[0]:       '0'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 0, 1);
Result:         
array[0]:       '0'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 1, 1);
Result:         
array[1]:       '1'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 2, 2);
Result:         
array[2]:       '2'
array[2]:       '2'

Running:        StringUtils.join(array, " ", 0, 3);
Result:         0 1 2
array[0]:       '0'
array[3]:       '3'

Running:        StringUtils.join(array, " ", 0, 4);
Result:         0 1 2 3
array[0]:       '0'
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
        at Test.printResult(Test.java:20)
        at Test.main(Test.java:12)
{code}
                
      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*"

Example code:
{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" };

                printResult(array, 0, 0);
                printResult(array, 0, 1);
                printResult(array, 1, 1);
                printResult(array, 2, 2);
                printResult(array, 0, 3);
                printResult(array, 0, 4);
        }

        public static void printResult(String[] array, int startIndex, int 
endIndex) {
                String str = StringUtils.join(array, " ", startIndex, endIndex);
                System.out.println("Running:\tStringUtils.join(array, \",\", " 
+ startIndex + " " + endIndex + ");");
                System.out.println("Result: \t" + str);
                System.out.println("array[" + startIndex + "]:\t'" + 
array[startIndex] + '\'');
                System.out.println("array[" + endIndex + "]:\t'" + 
array[endIndex] + '\'');
                System.out.println();
        }
}
{code}

Run it and tell me what is wrong.

{code}
Running:        StringUtils.join(array, " ", 0, 1);
Result:         
array[0]:       '0'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 0, 1);
Result:         
array[0]:       '0'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 1, 1);
Result:         
array[1]:       '1'
array[1]:       '1'

Running:        StringUtils.join(array, " ", 2, 2);
Result:         
array[2]:       '2'
array[2]:       '2'

Running:        StringUtils.join(array, " ", 0, 3);
Result:         0 1 2
array[0]:       '0'
array[3]:       '3'

Running:        StringUtils.join(array, " ", 0, 4);
Result:         0 1 2 3
array[0]:       '0'
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
        at Test.printResult(Test.java:20)
        at Test.main(Test.java:12)
{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

        

Reply via email to