Reputation: 916
I studying the stream, I encountered a question. I have a List I need to sort by the length of the string, all the strings where there is a match of uppercase characters, if there are no such, then sort by alphabet.
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);
I try to use matches, but I make a mistake somewhere, since nothing is output. How can I fix this?
Upvotes: 4
Views: 9909
Reputation: 809
This answer is for the regex matching part.
You are matching a three-character sequence A-Z
thus non of the Strings will match.
I tried to solve this part of your question.
A possible pattern is the following: .*[A-Z].*
You can check it here.
Upvotes: 2
Reputation: 32046
Few things to redress there would be, you need to ensure there are two different categorizations of strings, one which has any capital letter and another which doesn't. For this you can partition your list as :
Map<Boolean, List<String>> partitionedValues = phones.stream()
.collect(Collectors.partitioningBy(a -> containsUpperCase(a)));
where containsUpperCase
implementation would simply look like :
boolean containsUpperCase(String value) {
for (char ch : value.toCharArray()) {
if (Character.isUpperCase(ch)) {
return true;
}
}
return false;
}
Once you've partitioned the data as such you need to aggregate these into a single final list as:
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()));
your final output would then be visible as :
finalOutput.forEach(System.out::println);
Upvotes: 3