Home > OS >  Capitalize each word in a string, how does this code check the previous space
Capitalize each word in a string, how does this code check the previous space

Time:09-30

I recently came across this solution to writing a program that capitalizes each word in a string and I'm trying really hard to understand it, but I can't get over one hurdle.

public class test {
    public static void main(String[] args) {

        // create a string
        String message = "everyone loves java";

        // stores each characters to a char array
        char[] charArray = message.toCharArray();
        boolean foundSpace = true;

        for(int i = 0; i < charArray.length; i  ) {

            // if the array element is a letter
            if(Character.isLetter(charArray[i])) {

                // check space is present before the letter
                if(foundSpace) {

                    // change the letter into uppercase
                    charArray[i] = Character.toUpperCase(charArray[i]);
                    foundSpace = false;
                }
            }

            else {
                // if the new character is not character
                foundSpace = true;
            }
        }

        // convert the char array to the string
        message = String.valueOf(charArray);
        System.out.println("Message: "   message);
    }

I understand everything in this code except for how it checks if the previous character was a space. The comment says it does this with the if(foundSpace) statement, but I don't see any reason why that would work since it's never specified that it's looking for a space. Any pointers in the right direction would be appreciated

CodePudding user response:

Look at the code inside the loop, stripped down a bit:

for(int i = 0; i < charArray.length; i  ) {
  if(Character.isLetter(charArray[i])) {
    // check space is present before the letter
    if(foundSpace) {
      // Some code.
      foundSpace = false;
    }

    // Here, foundSpace is false.

  } else {
    foundSpace = true;
  }
}

The code doesn't care about what your variables or methods are called: it's checking if the character meets some criterion (Character.isLetter), and afterwards it has recorded whether or not the character met that criterion (in foundSpace).

This means that foundSpace contains whether the previous character met that criterion, and allows you to decide to do something on the current character based on what the previous one was: in your case, uppercase that character if the previous character didn't meet the criterion.

foundSpace is initially set to true, which means that the loop treats a string which starts with a letter as if there was a space before it, and so that will be capitalized.

Really, there is just a mismatch between the criterion used, and the name of the variable:

  • If the criterion should be "is it whitespace", use Character.isWhitespace as your criterion, and keep the flag name as foundSpace;
  • If the criterion really is "is it a letter", use Character.isLetter as your criterion, and name the flag foundLetter (and invert its sense, so check if (!foundLetter) etc, because it's easier to deal with "positive" checks (if (foundLetter)) rather than "negative" checks (if (!foundLetter))).

CodePudding user response:

foundSpace is only set to false if the condition:

    (Character.isLetter(charArray[i]))

is triggered.

If the condition is not triggered, aka if the character is not a letter, then foundSpace will be set to True.

This means that anything that is not a letter will set foundSpace equal to true. As Silvio pointed out, this includes other non space characters such as 1, $, and ".

It would be better instead of checking if the character is a letter, to instead check to see if charArray[i] is equal to a space.

Like so:

    boolean foundSpace = Character.isWhitespace(charArray[i])

More info about the Character class can be found below: https://www.geeksforgeeks.org/character-equals-method-in-java-with-examples/

The code you've shown could have some undesirable side effects - especially if foundSpace is relied upon later on - because it could potentially lead you to believe that a space exists in a word, when it's not a space at all but rather a character that isn't a letter like "$".

In the context of your entire program, this looks like:

public class test {
public static void main(String[] args) {

    // create a string
    String message = "everyone loves java";

    // stores each characters to a char array
    char[] charArray = message.toCharArray();
    boolean foundSpace = true;

    for(int i = 0; i < charArray.length; i  ) {
        if(Character.isWhitespace(charArray[i])){
            foundSpace = true;
        }
        else{
            foundSpace = false;
        }
        // if the array element is a letter
        if(Character.isLetter(charArray[i])) {
            // check space is present before the letter
            if(foundSpace) {

                // change the letter into uppercase
                charArray[i] = Character.toUpperCase(charArray[i]);
            }
        }
        else {
            // if the new character is not character
            // delete this condition if you don't plan to use it
        }
    }

    // convert the char array to the string
    message = String.valueOf(charArray);
    System.out.println("Message: "   message);
}

Some edits made to the code to fix compilation errors, thanks to those in the comments for your suggestions.

  • Related