179

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

String s = "edcba"  ->  "abcde"

15 Answers 15

275

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.

Sign up to request clarification or add additional context in comments.

9 Comments

The correct way would be to sort the code points. Unfortunately there is no String.toCodePointArray. (What order should we be sorting into, btw?)
The ICU project describes a code point order UTF-16 sort method: 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.
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é".
@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?
@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);
|
64

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é"
  }
}

6 Comments

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.
See Character.isHighSurrogate(char)
Somehow I think this will do... unless he wants to sort Strings containing Swahili or something :)
"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 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?
|
53

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());

3 Comments

@Dennis on which one exactly and why?
The first bit where you attempt to sort a String. It looks good but when I ran it against a large dataset it was quite a bit slower in comparison to Jon Skeets answer.
Please add imports
30

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"

3 Comments

What was the point in adding this answer 4 years after other people posted at least 3 identical answers
@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?
@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 :)
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);
}

5 Comments

the question asked for Native way in java, not using any other sorting algorithm.
Voted up because it was a useful solution, not because it was the requested answer.
@VikrantGoel "Native way in java" - what's not native about this approach? i don't see any 3rd party requirements. Do you?
This should be the correct answer. Like @NickCardoso said... nothing is more "Native way in java" than this.
average run time for Arrays.sort is nlogn on the other hand for insertion it is n square. its always favorable to use Arrays.sort
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.

1 Comment

you need import java.util.Arrays; or else it won't work
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);

2 Comments

Is this a joke? Posting identical answers to a question 8 years old? How lazy.
I am ignorant. Forgive me.
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())

Comments

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);
    }
}

Comments

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();
}

Comments

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

Comments

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());

Comments

0

Helped to convert and get sorted string

s = s.chars().boxed().sorted().map(Character::toString).sorted().collect(Collectors.joining())
        .toString();

1 Comment

Thank you for your answer! However, please notice that someone has already posted this exact answer.
-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);

}

Comments

-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

1 Comment

You should look again at >=. What happens with "mnmnmnm" as your string?