Delpux
Delpux

Reputation: 137

Comparing letter occurrence with comparator

I am having a problem with sorting a string array[], based on which strings have most letter 'p' in them, i.e., s1 (apple) would be before s2 (ape)...

I am learning how to implement Comparator to do this and use then s1.compareTo(s2) and lambda. The big question is, can't I somehow use a stream to do this ?

This is how I did it for my String array COUNTRIES in reversed alphabetic sorting

Comparator<String> reverseAlphabetic = (s1,s2) -> -s1.compareToIgnoreCase(s2);   

Arrays.sort(COUNTRIES,reverseAlphabetic);
System.out.println("\nCountries in reverse alphabetic order");
for (int i=0; i<10;i++)
    System.out.println("\t"+COUNTRIES[i]);

Upvotes: 0

Views: 284

Answers (1)

Hadi
Hadi

Reputation: 17299

Y̶o̶u̶ ̶c̶a̶n̶ ̶d̶o̶ ̶s̶o̶m̶e̶t̶h̶i̶n̶g̶ ̶l̶i̶k̶e̶ ̶t̶h̶i̶s̶ ̶:̶

Comparator<String> comparator = (str1, str2) ->
        ((str1.length() - str1.replaceAll("p", "").length()) -
         (str2.length() - str2.replaceAll("p", "").length()));
List<String> list = Arrays.asList("ape", "apple", "appple");
list.sort(comparator);

Actually my solution had fundamental mistakes. @Holger commented a solution in my deleted answer.

list.sort(Comparator
         .comparingLong((String s) -> s.chars().filter(c -> c == 'p').count()).reversed());

commented by @Holger

Your first variant is broken too, as a - b - c - d is not the same as a - b - (c - d). It just produces the desired result by accident; a different original order will lead to different results. Yet another reason not to use minus when you mean, e.g. Integer.compare(…, …). A correct and efficient comparator can be as simple as Comparator.comparingLong(s -> s.chars().filter(c -> c=='p').count()) (or to have most occurences first, Comparator.comparingLong((String s) -> s.chars().filter(c -> c=='p').count()).reversed()), though a old-fashioned counting loop would be even better

Upvotes: 1

Related Questions