171

Is there a native way to sort a String by its contents in java? E.g.

String s = "edcba"  ->  "abcde"
starblue
  • 55,348
  • 14
  • 97
  • 151

15 Answers15

259

toCharArray followed by Arrays.sort followed by a String constructor call:

import java.util.Arrays;

public class Test
{
    public static void main(String[] args)
    {
        String original = "edcba";
        char[] chars = original.toCharArray();
        Arrays.sort(chars);
        String sorted = new String(chars);
        System.out.println(sorted);
    }
}

EDIT: As tackline points out, this will fail if the string contains surrogate pairs or indeed composite characters (accent + e as separate chars) etc. At that point it gets a lot harder... hopefully you don't need this :) In addition, this is just ordering by ordinal, without taking capitalisation, accents or anything else into account.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    The correct way would be to sort the code points. Unfortunately there is no String.toCodePointArray. (What order should we be sorting into, btw?) – Tom Hawtin - tackline Mar 03 '09 at 11:58
  • 1
    The ICU project describes a code point order UTF-16 sort method: http://icu-project.org/docs/papers/utf16_code_point_order.html . I don't think Arrays.sort will destroy any supplementary characters due to the way the ranges are defined, but don't quote me. – McDowell Mar 03 '09 at 14:00
  • 2
    It maybe will not destroy anything, but the sort order is not optimal if you want to take into account uppercase and accents for example. This algorithm will sort "éDedCBcbAàa" as "ABCDabcdeàé" while, in English (US) locale for example, it would be more desirable to obtain "aAàbBcCdDeé". – eljenso Mar 03 '09 at 14:07
  • YiweiG, [your suggested edit](http://stackoverflow.com/review/suggested-edits/4666438) should have been a comment. Please let the poster decide if he agrees with your suggested modification rather than trying to change the substance of the code through an edit. – Adi Inbar Apr 27 '14 at 02:04
  • 1
    @YiweiG And in this case, the answer is: definitely not. `sorted` is already a `String`... what would you expect calling `toString()` on it to do? – Jon Skeet Apr 27 '14 at 06:16
  • Why mine is not working? `public static boolean uniqueCharacters(String s){ Arrays.sort(s.toCharArray()); String sorted = new String(s); for(int i = 1; i < sorted.length(); i++){ if(sorted.charAt(i) == sorted.charAt(i-1)){ return false; } } return true; }` I am trying to check if string has unique characters or not. But sorting is not working ... – Hengameh Aug 24 '15 at 03:08
  • 2
    @Hengameh: You're sorting a character array, but then ignoring it. You'd want `char[] c = s.toCharArray(); Arrays.sort(c); String sorted = new String(c);` – Jon Skeet Aug 24 '15 at 05:45
  • @JonSkeet oh, sorry thanks for letting me know, I have deleted the comment now – beginner Dec 01 '21 at 15:33
59

No there is no built-in String method. You can convert it to a char array, sort it using Arrays.sort and convert that back into a String.

String test= "edcba";
char[] ar = test.toCharArray();
Arrays.sort(ar);
String sorted = String.valueOf(ar);

Or, when you want to deal correctly with locale-specific stuff like uppercase and accented characters:

import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;

public class Test
{
  public static void main(String[] args)
  {
    Collator collator = Collator.getInstance(new Locale("fr", "FR"));
    String original = "éDedCBcbAàa";
    String[] split = original.split("");
    Arrays.sort(split, collator);
    String sorted = "";
    for (int i = 0; i < split.length; i++)
    {
      sorted += split[i];
    }
    System.out.println(sorted); // "aAàbBcCdDeé"
  }
}
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
eljenso
  • 16,789
  • 6
  • 57
  • 63
  • FYI: this method will split 32bit code points in two - Unicode characters with a value greater than 0xFFFF, creating strings with invalid values. Not an issue for French, but may cause problems for some locales. – McDowell Mar 03 '09 at 13:49
  • See Character.isHighSurrogate(char) – McDowell Mar 03 '09 at 13:52
  • 2
    Somehow I think this will do... unless he wants to sort Strings containing Swahili or something :) – eljenso Mar 03 '09 at 13:55
  • 3
    "I think this will do... unless he wants to sort Strings containing Swahili" -- I can see the slogan -- Unicode: when you want an easy way of localizing and translating your applications to *some* languages. Bzzt. Fail. Doing thing *almost* right means you *almost* don't have a bug to fix later. – Jonas Kölker Mar 03 '09 at 14:40
  • 1
    @Jonas I said I *think*, unless the OP wants to specify that it's absolutely necessary to support Swahili. I even prefer the simple solution without the locale, again unless the OP states that it is not sufficient. Ever heard of the YAGNI principle? – eljenso Mar 03 '09 at 15:24
  • Why mine is not working? `public static boolean uniqueCharacters(String s){ Arrays.sort(s.toCharArray()); String sorted = String.valueOf(s); for(int i = 1; i < sorted.length(); i++){ if(sorted.charAt(i) == sorted.charAt(i-1)){ return false; } } return true; }` I am trying to check if characters of a string are unique or not, and I use sorting. But every time I get 'true'! – Hengameh Aug 24 '15 at 03:19
50

In Java 8 it can be done with:

String s = "edcba".chars()
    .sorted()
    .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
    .toString();

A slightly shorter alternative that works with a Stream of Strings of length one (each character in the unsorted String is converted into a String in the Stream) is:

import java.util.stream.Collectors;
import java.util.stream.Stream;

String sorted =
    Stream.of("edcba".split(""))
        .sorted()
        .collect(Collectors.joining());
Marcin
  • 1,469
  • 14
  • 23
28

Convert to array of charsSortConvert back to String:

String s = "edcba";
char[] c = s.toCharArray();        // convert to array of chars 
java.util.Arrays.sort(c);          // sort
String newString = new String(c);  // convert back to String
System.out.println(newString);     // "abcde"
Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 1
    What was the point in adding this answer 4 years after other people posted at least 3 identical answers – Nick Cardoso Apr 16 '18 at 08:06
  • 3
    @NickCardoso I really don't remember, you're asking me about an answer I posted on my very early stages on Stack Overflow. Are you really waiting for explanation on that? – Maroun Apr 16 '18 at 08:09
  • 1
    @NickCardoso I'm **NOT** trying to provide an excuse for you at all. Your comment, and downvote, won't change anything for now. That's what I decided FOUR years ago, I don't see what's the point of bringing this up now :) – Maroun Apr 16 '18 at 08:13
22

A more raw approach without using sort Arrays.sort method. This is using insertion sort.

public static void main(String[] args){
    String wordSt="watch";
    char[] word=wordSt.toCharArray();

    for(int i=0;i<(word.length-1);i++){
        for(int j=i+1;j>0;j--){
            if(word[j]<word[j-1]){
                char temp=word[j-1];
                word[j-1]=word[j];
                word[j]=temp;
            }
        }
    }
    wordSt=String.valueOf(word);
    System.out.println(wordSt);
}
agaase
  • 1,562
  • 1
  • 15
  • 24
15
    String a ="dgfa";
    char [] c = a.toCharArray();
    Arrays.sort(c);
    return new String(c);

Note that this will not work as expected if it is a mixed case String (It'll put uppercase before lowercase). You can pass a comparator to the Sort method to change that.

amit
  • 10,612
  • 11
  • 61
  • 60
4

Procedure :

  1. At first convert the string to char array
  2. Then sort the array of character
  3. Convert the character array to string
  4. Print the string

Code snippet:

    String input = "world";
    char[] arr = input.toCharArray();
    Arrays.sort(arr);
    String sorted = new String(arr);
    System.out.println(sorted);
rashedcs
  • 3,588
  • 2
  • 39
  • 40
4
str.chars().boxed().map(Character::toString).sorted().collect(Collectors.joining())

or

s.chars().mapToObj(Character::toString).sorted().collect(Collectors.joining())

or

Arrays.stream(str.split("")).sorted().collect(Collectors.joining())
Peng
  • 1,393
  • 13
  • 19
2

Question: sort a string in java

public class SortAStringInJava {
    public static void main(String[] args) {

        String str = "Protijayi";
// Method 1
        str = str.chars() // IntStream
                .sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();

        System.out.println(str);
        // Method 2
        str = Stream.of(str.split(" ")).sorted().collect(Collectors.joining());
        System.out.println(str);
    }
}
Soudipta Dutta
  • 1,353
  • 1
  • 12
  • 7
1

A solution that uses the Stream API and also handles Unicode supplementary characters:

public static String sort(final String s) {
    return s.codePoints()
            .sorted()
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();
}
Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
0

You can also write up a counting sort algorithm to sort all the characters in an array if you would like to reduce your worst-case time complexity from nlogn to n

cron8765
  • 11
  • 3
0

However, the most efficient way is to use Arrays.sort as indicated by Jon Skeet, if you insist to use Java 8 streams, this could be another solution:

    String s = "edcba".chars().
    sorted().
    mapToObj(c->String.valueOf((char)c)).
    collect(Collectors.joining());
Kayvan Tehrani
  • 3,070
  • 2
  • 32
  • 46
0

Helped to convert and get sorted string

s = s.chars().boxed().sorted().map(Character::toString).sorted().collect(Collectors.joining())
        .toString();
  • Thank you for your answer! However, please notice that someone has already posted [this exact answer](https://stackoverflow.com/a/75965566/13927534). – Miss Skooter Apr 12 '23 at 19:11
-1
public static void main(String[] args) {
    String str = "helloword";   
    char[] arr;
    List<Character> l = new ArrayList<Character>();
    for (int i = 0; i < str.length(); i++) {
        arr = str.toCharArray();
        l.add(arr[i]);

    }
    Collections.sort(l);
    str = l.toString();
    System.out.println(str);
    str = str.replaceAll("\\[", "").replaceAll("\\]", "")
            .replaceAll("[,]", "");
    System.out.println(str);

}
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
-2

Without using Collections in Java:

import java.util.Scanner;

public class SortingaString {
    public static String Sort(String s1)
    {
        char ch[]=s1.toCharArray();         
        String res=" ";
        
        for(int i=0; i<ch.length ; i++)
        {
            for(int j=i+1;j<ch.length; j++)
            {
                if(ch[i]>=ch[j])
                {
                    char m=ch[i];
                    ch[i]=ch[j];
                    ch[j]=m;
                }
            }
            
            res=res+ch[i];
            
        }

        return res;
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("enter the string");
        
        String s1=sc.next();
        String ans=Sort( s1);
        
        System.out.println("after sorting=="+ans);
    }
}

Output:

enter the string==

sorting

after sorting== ginorst

Community
  • 1
  • 1