【问题标题】:Using stream API to set strings all lowercase but capitalize first letter使用流 API 将字符串设置为小写但首字母大写
【发布时间】:2019-05-13 00:17:51
【问题描述】:

我有一个List<String>,通过仅使用流 API 我将所有字符串设置为小写,将它们从最小字符串排序到最大并打印它们。我遇到的问题是将字符串的第一个字母大写。

这是我通过.stream().map()做的事情吗?

public class Main {

    public static void main(String[] args) {

        List<String> list = Arrays.asList("SOmE", "StriNgs", "fRom", "mE", "To", "yOU");
        list.stream()
            .map(n -> n.toLowerCase())
            .sorted((a, b) -> a.length() - b.length())
            .forEach(n -> System.out.println(n));;

    }

}

输出:

me
to
you
some
from
strings

期望的输出:

Me
To
You
Some
From
Strings

【问题讨论】:

    标签: java java-8 mapping java-stream capitalization


    【解决方案1】:

    这样就足够了:

     list.stream()
         .map(n -> n.toLowerCase())
         .sorted(Comparator.comparingInt(String::length))
         .map(s -> Character.toUpperCase(s.charAt(0)) + s.substring(1))
         .forEachOrdered(n -> System.out.println(n));
    
    1. 请注意,我已经更改了比较器,这基本上是惯用的做法。
    2. 在将第一个字母排序为大写后,我添加了一个map 操作。

    【讨论】:

    • 可以,谢谢!我不知道我可以对同一个流多次使用 Map。
    • @Devin 您可以链接任意数量的中间操作。
    • 请记住,forEach 没有排序保证,因此要确保按排序顺序查看元素,您必须使用 forEachOrdered
    • @Devin,根据需要使用尽可能多的中间操作(filter/map/distinct/sorted/peek)。应用终端方法(reduce/collect/foreach)后,您已经“结束”了流。
    • 空字符串会失败。使用.map(s -&gt; s.isEmpty() ? "" : Character.toUpperCase(s.charAt(0)) + s.substring(1))
    【解决方案2】:
    list.stream()
        .map(s -> s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase())
        .sorted(Comparator.comparingInt(String::length))
        .forEach(System.out::println);
    

    为了可读性,应该将执行大写的行移到方法中,

    public class StringUtils {
        public static String capitalise(String s) {
            return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
        }
    }
    

    所以你可以通过一个雄辩的方法参考来参考它:

    list.stream()
        .map(StringUtils::capitalise)
        .sorted(Comparator.comparingInt(String::length))
        .forEach(System.out::println);
    

    【讨论】:

    • 这将表现出比接受的答案更好的局部性,后者会在排序的任一侧分割地图。
    • @AlexReinking 虽然同意你的观点,但我只想指出,我在发帖时决定不使用一个地图操作的唯一原因是为了保留每个中间操作的逻辑简短易懂,从而使 OP 更容易理解。请记住,在一天结束时,OP 似乎是 Streams API 的新人,谈论其他任何事情都是一种奖励,但会远离他们的主要观点,即简单地将第一个字符大写。顺便说一句,现在看来 OP 知道可以使用多个“相同”的中间操作:)。
    【解决方案3】:

    您可以为此使用 Apache Commons Lang 中的 WordUtils::capitalizeFully

     list.stream()
         .sorted(Comparator.comparingInt(String::length))
         .map(WordUtils::capitalizeFully)
         .forEach(System.out::println);
    

    【讨论】:

    • OP 只想将第一个字母大写。再说了,你没有提到WordUtils是从哪里来的……
    • @AndrewTobilko WordUtils::capitalizeFully 就是这样做的。我已经提到了WordUtils 的来源。
    • 新代码应使用此方法的commons-text 版本,因为commons-lang 已被弃用。
    猜你喜欢
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2021-01-15
    • 1970-01-01
    • 2011-05-12
    • 2016-02-15
    相关资源
    最近更新 更多