如何使用流比较字符串字符?

时间:2019-01-20 08:17:52

标签: java java-stream

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

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);

我尝试使用匹配项,但是由于没有任何输出,我在某个地方犯了一个错误。我该如何解决?

2 个答案:

答案 0 :(得分:2)

要解决的事情很少,您需要确保有两种不同的字符串分类,一种具有大写字母,而另一种则没有。为此,您可以将列表划分为:

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);

答案 1 :(得分:2)

此答案用于正则表达式匹配部分。 您正在匹配三个字符的序列A-Z,因此所有字符串都不匹配。

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