4
\$\begingroup\$

I recently was given a task to capitalize the first character of a string provided the string does not begin with a non-alphabet. Below are the requirements and my implementation. Just want to know if there is a more efficient way to implement this.

Requirements

Please implement this method to capitalize all first letters of the words in the given String. All other symbols shall remain intact. If a word starts not with a letter, it shall remain intact too.Assume that the parameter String can only contain spaces and alphanumeric characters. NOTE: please keep in mind that the words can be divided by single or multiple spaces.The spaces also can be found at the beginning or the end of the parameter string,and you need to preserve them.

public static String capitalizeFirstLetters(String s) {
        StringBuilder wordsWithFirstLetterCapitalized = new StringBuilder();
        s = s.trim();
        String words[] = s.split("\\ ");
        if (words.length <= 1) {
            if(words.toString().matches("^[A-Za-z].*$")) {  
            words.toString().toUpperCase();
            wordsWithFirstLetterCapitalized.append(words);
            }
            else {
                wordsWithFirstLetterCapitalized.append(words);
            }
        }

        else {
            for (String word : words) {
                if (word.matches("^[A-Za-z].*$")) {
                    word = word.substring(0, 1).toUpperCase() + word.substring(1);
                    wordsWithFirstLetterCapitalized.append(word);
                    wordsWithFirstLetterCapitalized.append(" ");
                }
                else {
                    wordsWithFirstLetterCapitalized.append(word);
                }
            }
        }

        return wordsWithFirstLetterCapitalized.toString();
    }
\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$

It appears whitespace is destroyed instead of preserved, see your "NOTE". I suspect input like " 123 456 " will output "123456" destroying outer and inner space. Similarly

"a     b"
will become "A B", as split will return a lot of empty strings when splitting more than one space. How about treating it as a stream and if the previous character is whitespace and the next character is in a-z, upper case it, and emit the character and update your previous character placeholder. You could probably do this with a single regular expression.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks. I will try a single regex that can match all conditions. \$\endgroup\$
    – Don Who
    Oct 13, 2015 at 19:17
  • 3
    \$\begingroup\$ >You could probably do this with a single regular expression. "\\b(\\w)" => replace all with uppercase \$\endgroup\$ Oct 13, 2015 at 19:29
0
\$\begingroup\$

You might want to look into the StringTokenizer class. http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html

This will take any String as input and split it at spaces by default so you are left with all the words in the String. It could also split it at different characters if you give them as a parameter.

Here is a small example I set up quickly.

    String input = "String to be capitalized";
    StringTokenizer tokenizer = new StringTokenizer(input);
    StringBuilder builder = new StringBuilder();

    while(tokenizer.hasMoreTokens()){
        String word = tokenizer.nextToken();
        word = word.substring(0,1).toUpperCase() + word.substring(1);
        builder.append(word);
        builder.append(" ");
    }

    String capitalized = builder.toString();
    System.out.println(capitalized);
\$\endgroup\$
1
  • 2
    \$\begingroup\$ FYI, the documentation for StringTokenizer states the following: "StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead." It can still be used, but String.split is preferred. \$\endgroup\$
    – cbojar
    Oct 14, 2015 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.