Home > Mobile >  Using comparator for char array, but get no suitable method found
Using comparator for char array, but get no suitable method found

Time:05-18

I am trying to use the value of freq to sort all the a-z chars. However it is not working. Could someone explain why the following code is not working please? And how can I sort the array as I want? Thank you.

        char[] chars = new char[26];
        int[] freq = new int[26];
        for(int i = 0;i<26;i  ){
            chars[i] = (char)(i 'a');
        }
        for(char c:s.toCharArray()){
            freq[c-'a']  ;
            if(freq[c-'a']>(s.length() 1)/2){
                return "";
            }
        }
        Arrays.sort(chars, (a, b)->(freq[b-'a'] - freq[a-'a']));

error: no suitable method found for sort(char[],(a,b)->(fr[...]'a'])) Arrays.sort(chars, (a, b)->(freq[b-'a'] - freq[a-'a'])); ^ method Arrays.<T#1>sort(T#1[],Comparator<? super T#1>) is not applicable (inference variable T#1 has incompatible bounds equality constraints: char lower bounds: Object) method Arrays.<T#2>sort(T#2[],int,int,Comparator<? super T#2>) is not applicable (cannot infer type-variable(s) T#2 (actual and formal argument lists differ in length)) where T#1,T#2 are type-variables: T#1 extends Object declared in method <T#1>sort(T#1[],Comparator<? super T#1>) T#2 extends Object declared in method <T#2>sort(T#2[],int,int,Comparator<? super T#2>)

CodePudding user response:

The Answer by Supritam is correct. I’ll add a workaround.

The char type is legacy, essentially broken. As a 16-bit value, char is physically incapable of representing most characters.

Instead use code point integer numbers to work with individual characters.

Map of code point to count

Rather than use a pair of arrays, use a Map, a collection of key-value pairings.

Map< Integer , Integer > map = new HashMap<>();
someString
        .codePoints()
        .forEach( 
            codePoint -> map.put( codePoint , map.containsKey( codePoint ) ? map.get( codePoint )   1 : 1 ) 
        ) ;

We now have a count of occurrences of each code point. But the goal in the Question is to report results sorted by the count of occurrences.

That count is the value on our map. So we need to sort the map by value. There are several ways to do that, as discussed in this article.

List< Entry< Integer , Integer > > list = new ArrayList<>( map.entrySet() );
list.sort( 
    Entry.comparingByValue().thenComparing( Entry.comparingByKey() ) ;
);
list.forEach( ( Entry< Integer , Integer > entry ) -> System.out.println( entry.getValue()   " occurrences of "   Character.toString( entry.getKey() ) ) );

All that code is untested. Hopefully it is close enough to working to guide you.

CodePudding user response:

According to the javadocs, Arrays.sort with a comparator is only applicable on Objects not primitives.

Arrays.sort(char[]) sorts on numerical order.

Just to solve your problem:

    String s = "hello";
    Map<Character, Integer> returnMap = new HashMap<Character, Integer>();
    Map<Character, Integer> map = new HashMap<Character, Integer>();
    for (int i = 0; i < 26; i  ) {
        map.put (Character.valueOf((char)(i   'a')), 0);
    }

    for (char c : s.toCharArray()) {
        Integer freq = map.get(Character.valueOf(c));
        map.put(Character.valueOf(c),  freq);
    }
    List<Map.Entry<Character,Integer>> listToSort = new LinkedList<>(map.entrySet());
    Collections.sort(listToSort, (m1, m2)->(
        m2.getValue().compareTo(m1.getValue())
            )
    );
    listToSort.forEach(entry -> System.out.println(entry.getKey() ":" entry.getValue()));
  • Related