【问题标题】:How to compare string characters using stream?如何使用流比较字符串字符?
【发布时间】:2019-01-20 08:17:52
【问题描述】:

我在研究流,我遇到了一个问题。我有一个列表,我需要按字符串的长度排序,所有匹配大写字符的字符串,如果没有,则按字母排序。

List<String> phones = new ArrayList<>();
Collections.addAll(phones, "iPhone X", "Nokia 9", "Huawei Nexus 6P",
        "Samsung Galaxy S8", "LG G6", "Xiaomi MI6", "Sony Xperia Z5",
        "Asus Zenfone 3", "Meizu Pro 6", "Heizu Pro 6",
        "pixel 2");

phones.stream().filter(s -> s.matches("A-Z")).sorted(Comparator.comparingInt(String::length)).forEach(System.out::println);

我尝试使用匹配,但我在某处犯了错误,因为没有任何输出。我该如何解决这个问题?

【问题讨论】:

标签: java java-stream


【解决方案1】:

几乎没有什么需要纠正的,您需要确保字符串有两种不同的分类,一种有大写字母,另一种没有。为此,您可以将列表划分为:

Map<Boolean, List<String>> partitionedValues = phones.stream()
        .collect(Collectors.partitioningBy(a -> containsUpperCase(a)));

containsUpperCase 的实现看起来就像:

boolean containsUpperCase(String value) {
    for (char ch : value.toCharArray()) {
        if (Character.isUpperCase(ch)) {
            return true;
        }
    }
    return false;
}

一旦您对数据进行了这样的分区,您需要将它们聚合到一个最终列表中:

List<String> finalOutput = partitionedValues.get(Boolean.TRUE) // with upper case
        .stream()
        .sorted(Comparator.comparing(String::length)) // sorted by length
        .collect(Collectors.toList());

finalOutput.addAll(partitionedValues.get(Boolean.FALSE) // without uppercase
        .stream()
        .sorted(Comparator.naturalOrder()) // sorted naturally
        .collect(Collectors.toList()));

您的最终输出将显示为:

finalOutput.forEach(System.out::println);

【讨论】:

    【解决方案2】:

    此答案适用于正则表达式匹配部分。 您正在匹配一个三字符序列A-Z,因此不会匹配任何字符串。

    我试图解决你的这部分问题。 一种可能的模式如下:.*[A-Z].* 您可以查看here

    【讨论】:

    • 应该可以优化一下,不过我觉得目前还可以。
    • 感谢指正。我使正则表达式过于复杂。
    猜你喜欢
    • 2022-07-22
    • 2017-04-14
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2022-10-15
    • 2020-01-31
    相关资源
    最近更新 更多