restfulblue
restfulblue

Reputation: 43

Sorting array of char using Arrays.sort

I'm trying to sort array of char using Arrays.sort function. I'm using the following code:

class Solution {
    public String customSortString(String S, String T) {
        Map<Character, Integer> poses = new HashMap<>(S.length());

        for(int i = 0 ; i < S.length() ; i++){
            poses.put(S.charAt(i), i);
        }

        char[] tmpArr = T.toCharArray();

        Arrays.sort(tmpArr , new Comparator<Character>(){ 

            @Override
            public int compare(Character c1, Character c2) {   
                Integer aPos = poses.get(c1);
                Integer bPos = poses.get(c2);

                if(aPos == null || bPos == null)
                    return 0;

                return Integer.compare(aPos,bPos);
            } 
        });

        return new String(tmpArr);

    }
}

But I'm getting this error:

Error:(14, 19) java: no suitable method found for sort(char[],<anonymous java.util.Comparator<java.lang.Character>>)
    method java.util.Arrays.<T>sort(T[],java.util.Comparator<? super T>) is not applicable
      (inference variable T has incompatible bounds
        equality constraints: char
        upper bounds: java.lang.Character,java.lang.Object)
    method java.util.Arrays.<T>sort(T[],int,int,java.util.Comparator<? super T>) is not applicable
      (cannot infer type-variable(s) T
        (actual and formal argument lists differ in length))

What am I doing wrong? It looks like there is no auto unboxing to Character. How can I make this work?

Upvotes: 4

Views: 8163

Answers (4)

davidxxx
davidxxx

Reputation: 131316

It looks like there is no auto unboxing to Character.

To be precise, primitive to object conversion at compile time is called boxing. Unboxing is the reverse way.
And yes Character/char provides an autoboxing feature but it doesn't work in this way. Here the primitives/wrapper counterparts are in an array or a list : so no boxing possible here.

That compiles :

char a = Character.valueOf('a'); // compile
Character aa  = 'a'; // compile

But that does not :

List<Character> charList = ...;
char[] charArray= ...;
charList = charArray; // doesn't compile
charArray = charList; // doesn't compile

How can I make this work?

Sorting an array of char with a specific Comparator is not conventional.
So not surprising that the Arrays API doesn't provide such a method.
Generally, Comparator and Comparable implementations rely only on the state of the compared objects to return the result, not on an external variable as in your example.
Similarly the Arrays API doesn't provide any method to create a Stream of char because streaming characters is also not a very conventional need.
So you don't have a straight built-in way to solve your issue.

In your situation, I would rely onArrays.stream(String.split()) to get a String for each character of the original String and I would apply the sort and finish with a joining :

String originalValue = "...";
String afterSortValue =
    Arrays.stream(originalValue.split(""))
          .sorted((o1, o2) -> {
                    Integer aPos = poses.get(o1);
                    Integer bPos = poses.get(o2);
                    if (aPos == null || bPos == null)
                      return 0;
                    return Integer.compare(aPos, bPos);
                  }
          )
         .collect(Collectors.joining());

This should be the most direct way without using external libraries.

Upvotes: 3

Joakim Danielson
Joakim Danielson

Reputation: 51892

There already exist a sort method for char[] so

 Arrays.sort(tmpArr);

So the complete flow is

char[] tmpArr = T.toCharArray();
Arrays.sort(tmpArr);
return new String(tmpArr);

Upvotes: 0

H&#252;lya
H&#252;lya

Reputation: 3433

public static void sort(T[] a,Comparator c)

Sorts the specified array of objects according to the order induced by the specified comparator.

You can't use primitives, Comparator works only with objects.

char is a primitive data type in java so you should change tmpArr as:

Character[] tmpArr = new Character[T.length()];

for (int i = 0; i < T.length(); i++) {
    tmpArr[i] = new Character(T.charAt(i));
}

Upvotes: 1

Krupal Shah
Krupal Shah

Reputation: 9187

char[] tmpArr = T.toCharArray();

Here is the mistake, you can't use premitives with comparator. You need to convert it to Character[].

You could do something like below with Apache commons-lang:

char[] charArray = str.toCharArray();
Character[] tmpArr = ArrayUtils.toObject(charArray);

Here are some good ways to convert.

Upvotes: 5

Related Questions