3

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
restfulblue
  • 33
  • 1
  • 5

4 Answers4

4
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.

Krupal Shah
  • 8,949
  • 11
  • 57
  • 93
2

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.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

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));
}
Hülya
  • 3,353
  • 2
  • 12
  • 19
0

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);
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • The question talk about using sort with comparator. This flow would not work for the same. – Ankit Garg Jul 14 '21 at 13:45
  • based on your intention I have neutralized my vote, however I still believe that you should mention this answer is alternative answer and does not solve the question OP asked. Otherwise it makes the whole feed convoluted and difficult to find the answer which is covers the actual question. – Ankit Garg Jul 19 '21 at 23:26