简体   繁体   中英

Java Stream .map capitalize first letter only

I'm trying to sort my list alphabetically and also capitalize the first letter of each name.

When I do toUpperCase, it capitalizes every letter. If I were to print it without using .map , I would do ( topNames2017.substring(0, 1).toUpperCase() + topNames2017.substring(1) ) which works fine, but I don't know how to apply it here

List<String> topNames2017 = Arrays.asList(
            "Amelia",
            "Olivia",
            "emily",
            "Isla",
            "Ava",
            "oliver",
            "Jack",
            "Charlie",
            "harry",
            "Jacob"
    );


      topNames2017
            .stream()
            .map(String::toUpperCase)
            .sorted()
            .forEach(System.out::println);

You'll need to use a lambda to get your current attempt to work, example:

.map(name -> name.substring(0, 1).toUpperCase() + name.substring(1))

The name identifier above represents the current string passed to the map operation.

Alternatively, it can also be done like this:

.map(name -> Character.toUpperCase(name.charAt(0)) + name.substring(1))

If you want to maintain the use of method reference then you can define your own function like this:

static String capitaliseFirstLetter(String name){
      return name.substring(0, 1).toUpperCase() + name.substring(1);
}

Now, you can do:

topNames2017.stream()
            .map(Main::capitaliseFirstLetter) // replace Main with the class containing the capitaliseFirstLetter method
            .sorted()
            .forEach(System.out::println);

If you can use Apache Commons, I would suggest WordUtils.capitalize(String) like

topNames2017.stream()
        .map(WordUtils::capitalize)
        .sorted()
        .forEachOrdered(System.out::println);

If you can't use that, then you might do something like

topNames2017.stream()
        .map(x -> x.substring(0, 1).toUpperCase() + x.substring(1))
        .sorted()
        .forEachOrdered(System.out::println);

In either case, if you are sorting, make sure to use forEachOrdered .

Other answers tell you to use one of the following:

name.substring(0, 1).toUpperCase() + name.substring(1)
Character.toUpperCase(name.charAt(0)) + name.substring(1)
StringUtils.capitalize(name) // Apache Commons Lang
WordUtils.capitalize(name) // Apache Commons Lang (deprecated)

While those all work for Unicode characters in the Basic Multilingual Plane , there are letters in the Supplementary Planes that won't be capitalized that way. For reference, letters in the Supplementary Planes exist in the following Blocks:

You should also use toTitleCase , not toUpperCase . This makes a difference for the following characters (showing lowercase, titlecase, and uppercase):

Most people don't care about the above, but a full implementation of "capitalize first letter only" should take them into consideration.

Something like this would do:

static String capitalizeFirstLetter(String s) {
    if (s == null || s.isEmpty())
        return s;
    int codePoint = s.codePointAt(0);
    int codePointTitle = Character.toTitleCase(codePoint);
    if (codePointTitle == codePoint)
        return s; // Nothing to capitalize
    return new String(new int[] { codePointTitle }, 0, 1)
         + s.substring(s.offsetByCodePoints(0, 1));
}

You then use that instead of String::toUpperCase :

.map(MyClass::capitalizeFirstLetter)

Or simply use apache-commons StringUtil.capitalize() I that it's just good to know about it.

.map(StringUtils::capitalize)

More here: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#capitalize(java.lang.String)

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

public class Task1c {

    public static void main (String args[]){

            List<String> topNames2017 = Arrays.asList(
                    "Amelia", 
                    "Olivia", 
                    "emily", 
                    "Isla", 
                    "Ava", 
                    "oliver", 
                    "Jack",
                    "Charlie", 
                    "harry", 
                    "Jacob"
            );
    topNames2017
        .stream()
        .map(name->{return Character.toUpperCase(name.charAt(0))+name.substring(1);})
        .sorted()
        .forEach(System.out::println);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM