for loop on String length weirdly skipping some chars

Viewed 196

As mentioned in the title, I am running for loop on a string being read from a file, trying to delete every - character, But it is weirdly deleting some and skipping others. This is the String am working on : enter image description here

this is my function :

        System.out.println(newSeq);
        System.out.println(" String before deleteing -  = " +newSeq + "   length  = " + newSeq.length());
        for (int i = 0; i < newSeq.length(); i++) {
            System.out.println("char at : " + i + " = " + newSeq.charAt(i) );
            // Delete every -
            if ( newSeq.charAt(i) == '-'){
                StringBuilder lineString = new StringBuilder(newSeq);
                lineString.deleteCharAt(i);
                newSeq = lineString.toString();
            }
        }
        System.out.println("String after deleting -  = " + newSeq);

output :

enter image description here

6 Answers

In case you don't need to reinvent the wheel, Java already has a replace method:

newSeq = newSeq.replace("-", "");

You have a problem because you changed newSeq in the loop.

Suppose the input is: "1--3". On the second iteration, char will be -. Then you will replace input with "1-3". The next third iteration with index 2 will try to check the third char but the third char will be 3.

You can do it with replace:

    input.replace("-", "")

Or with regex:

    input.replaceAll("-+", "")

Or with loop:

    var input = "1--3";
    StringBuilder lineString = new StringBuilder();
    for (char item : input.toCharArray()) {
        if (item != '-'){
            lineString.append(item);
        }
    }
    System.out.println(lineString.toString());

Or with stream:

    var input = "1--3";
    var output = Arrays.stream(input.split(""))
            .filter(character -> !character.equals("-"))
            .collect(Collectors.joining());
    System.out.println(output);

First, worth mentioning, you are iterating over an array of chars, which you are then changing in a loop.

Without diving deeply into the issue I would guess what is happening in your result string has only the last - removed, because of the object re-assigning done in the loop.

In order to do this task correctly, you need to use a new variable or use a .replace method on the string, which will replace each found character or part of the string with another.

To make it properly, still using a for loop I would advice you to create a new string called result for example, and then concatenate it with those characters that are allowed:

String result = "";
for (int i = 0; i < newSeq.length(); i++) {
    if ( newSeq.charAt(i) != '-'){
        // this character is allowed, add it to the result
        result += newSeq.charAt(i);
    }
}
      // Delete every -
        if ( newSeq.charAt(i) == '-'){
            StringBuilder lineString = new StringBuilder(newSeq);
            lineString.deleteCharAt(i);
            newSeq = lineString.toString();
        }

This code is the problem. You are deleting a character & reassigning the reduced length string again. So the positions of right hand characters after the deletion will be shifted one position to left side. So you are getting unpredictable result.

Put it in a StringBuilder and delete starting at the end. That way your index doesn't get out of sync. If you start from the beginning you will miss adjacent characters. Of course, this just fixes the problem with your chosen method. Using String.replace() is the simplest way.

String newSeq = "UCGU----ACAGU";
System.out.println(newSeq);
StringBuilder sb = new StringBuilder(newSeq);
for (int i = sb.length() - 1; i >= 0; i--) {
    if (sb.charAt(i) == '-') {
        sb.deleteCharAt(i);
    }
}
newSeq = sb.toString();

System.out.println(newSeq);

Prints

UCGUACAGU

You can use .replaceAll() method, like this:

public static void main(String[] args) {
    
    String newSeq = "UCGU---AGAGU";
    
    System.out.println(newSeq);
    
    System.out.println("String before deleting '-': " + newSeq + ", length: " + newSeq.length() + "\n");
    
    for (int i = 0; i < newSeq.length(); i++) {
        System.out.println("Char at " + i + ": " + newSeq.charAt(i));            
    }
    
    newSeq = newSeq.replaceAll("-", "");
    
    System.out.println("\nString after deleting '-': " + newSeq);
}
Related