24

I have String[] array like

{"3","2","4","10","11","6","5","8","9","7"}

I want to sort it in numerical order, not in alphabetical order.

If I use

Arrays.sort(myarray);

I obtain

{"10","11","2","3","4","5","6","7","8","9"}

instead of

{"2","3","4","5","6","7","8","9","10","11"}
5
  • 3
    If you have strings you want to use as numbers, why don't you convert them to an appropriate, numeric type? Then when you're done with using them as numbers, you can always convert them back to strings again... If you want to go the harder route: create a custom Comparator<String> for the purpose... Commented Mar 8, 2013 at 8:43
  • Cant you loop through the array and convert them into ints Commented Mar 8, 2013 at 8:44
  • I read about Comparators, but what is the most efficient way? Compator or simple converting? Commented Mar 8, 2013 at 8:52
  • Read my comment below: it will always be more efficient to convert the whole array first because all sorting algorithms take more comparisons than the size of the list. Commented Mar 8, 2013 at 8:53
  • If you are using String array to sort by Arrays.sort() then there is no way left for you to sort them as number.Because you can not even change equals method and anyway after all number array is the best choice. Commented Mar 8, 2013 at 8:56

10 Answers 10

28

Try a custom Comparator, like this:

    Arrays.sort(myarray, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
        }
    });
Sign up to request clarification or add additional context in comments.

2 Comments

I like the succinctness of this solution, but there is a bit of a performance hit compared to pre-converting the array because we convert a String to an int every time we compare: since the number of comparisons is always greater than the size of the list, we are doing more conversions than necessary. I don't know if performance is an issue for OP but worth bearing in mind.
True, though I would often use a quick and elegant solution over a more thoroughly performance-tuned one until I know there is a need for the latter.
5

I think by far the easiest and most efficient way it to convert the Strings to ints:

int[] myIntArray = new int[myarray.length];

for (int i = 0; i < myarray.length; i++) {
    myIntArray[i] = Integer.parseInt(myarray[i]);
}

And then sort the integer array. If you really need to, you can always convert back afterwards:

for (int i = 0; i < myIntArray.length; i++) {
    myarray[i] = "" + myIntArray[i];
}

An alternative method would be to use the Comparator interface to dictate exactly how elements are compared, but that would probably amount to converting each String value to an int anyway - making the above approach much more efficient.

1 Comment

Just a suggestion: perhaps Integer.toString(myIntArray[i]) would illustrate the type conversion more explicitly than "" + myIntArray[i]
3

I found this article about sorting strings by numeric sorting also for strings that may or may not contain numbers:

The Alphanum Algorithm

There is a Java implementation example linked from the article. With that class you should be able to sort your arrays numerically like this:

Arrays.sort(myarray, new AlphanumComparator());

1 Comment

The provided link is dead, the implementation can still be found on SO: stackoverflow.com/questions/47170839/…
2

U can use sol-1 if it contains only numbers in string format.

Solution-1: -

String []arr = {"3","2","4","10","11","6","5","8","9","7"};
        Set<Integer> set = new TreeSet<Integer>();
        Arrays.sort(arr);
        for(String s:arr){
            System.out.print(s+"  ");
            set.add(Integer.parseInt(s));
        }
        System.out.println(set);
        Integer i = new Integer("4f");
        System.out.println(i);

Solution-2:-

String []arr = {"3","2","4","10","11","6","5","8","9","7","jgj","ek"};
        Set<Integer> intSet = new TreeSet<Integer>();
        Set<String> strSet = new TreeSet<String>();
        Arrays.sort(arr);
        for(String s:arr){
            try {
                int i = Integer.parseInt(s);
                intSet.add(i);
            } catch (NumberFormatException e) {
                strSet.add(s);
            }
        }
        List<String> result = new ArrayList<String>();
        for(int val:intSet){
            result.add(val+"");
        }
        result.addAll(strSet);
        System.out.println(result);
    }

Solution-3:-

Write one CustomComparator class and pass it to the sort() method.

public class CustomComparator implements Comparator<String>{

    @Override
    public int compare(String s1, String s2) {
        Integer i1=null;
        Integer i2=null;
        try {
            i1 = Integer.parseInt(s1);
        } catch (NumberFormatException e) {
        }

        try {
            i2 = Integer.parseInt(s2);
        } catch (NumberFormatException e) {
        }

        if(i1!=null && i2!=null){
            return i1.compareTo(i2);
        }else{
            return s1.compareTo(s2);
        }
    }

}


public static void main(){
String []arr = {"3","2","4","10","11","6","5","8","9","7","jgj","ek"};
Arrays.sort(arr, new CustomComparator());
        for(String s:arr){
            System.out.print(s+"  ");
        }
}

Comments

2

If all elements if your String array represent numbers, and if the numbers are always positive, then there is a simple way to sort numerically without a limit to the value of the number.

This is based on the fact that a number with a larger number of digits is, in that case, always higher than a number with a smaller number of digits.

You first compare the number of digits, and then (only if the number of digits is the same) you compare the value alphabetically:

Arrays.sort(array,
            Comparator.comparing(String::length).thenComparing(Function.identity()));

Comments

2

in jdk8, you can write this code with lambda.

        List<String> list = Arrays.asList("3", "2", "4", "10", "11", "6", "5", "8", "9", "7");
        list.sort(Comparator.comparingInt(Integer::valueOf));
        list.forEach(System.out::println);

especially such as input

String[]{"3.b", "2.c", "4.d", "10.u", "11.a", "6.p", "5.i", "8.t", "9.e", "7.i"}

you can use string.subString to chose which value is you really want to sort.
like

 files.sort(Comparator.comparingInt(a -> Integer.valueOf(a.substring(0, a.indexOf(".")))));

Comments

1

Your desired output contains the numerical order of corresponding integers of your strings. So simply you cannot avoid conversion of strings to integers. As an alternative comparator to vikingsteve's you can use this:

Arrays.sort(array, new Comparator<String>() {
    @Override
    public int compare(String str1, String str2) {
        return Integer.parseInt(str1) - Integer.parseInt(str2);
    }
});

Comments

1
public class test1 {

    public static void main(String[] args) 
    {
        String[] str = {"3","2","4","10","11","6","5","8","9","7"};
        int[] a = new int[str.length];
        for(int i=0;i<a.length;i++)
        {
            a[i]=Integer.parseInt(str[i]);
        }
        Arrays.sort(a);
        for(int i=0;i<a.length;i++)
        {
            str[i]=String.valueOf(a[i]);
        }
    }

}

Comments

0

This is the best solution I could come with, we can't convert to integer when the string is huge, this method sort an array of strings

public static void sortListOfStringsAsNumbers(List<String> unsorted) {        
    String min = "";
    for (int i = 0; i < unsorted.size(); i++){
        min = unsorted.get(i);
        int indexMin = i;
        for (int j = i + 1; j < unsorted.size(); j++){
            if (unsorted.get(j).length() < min.length()){
                min = unsorted.get(j);
                indexMin = j;
            }else if (unsorted.get(j).length() == min.length()){
                for (int x = 0; x < unsorted.get(j).length(); x ++){
                    if (unsorted.get(j).charAt(x) < min.charAt(x)){
                        min = unsorted.get(j);
                        indexMin = j;
                    }else if (unsorted.get(j).charAt(x) > min.charAt(x)){
                        break;
                    }
                }
            }
        }
        if (indexMin != i){
            String temp = unsorted.get(i);
            unsorted.set(i, min);
            unsorted.set(indexMin, temp);
        }
                    
    }

}

Comments

0

All the solutions are for only integer numbers. what if the array contains floating numbers as well?

Here is the best solution which allows you to sort any type of value in the string.

import java.math.BigDecimal;
import java.util.*;

class Sort
{
 public static void main(String...arg)
 {
  String s[]={"-100","50","0","56.6","90","0.12",".12","02.34","000.000"};

  System.out.println("\n"+Arrays.toString(s)); //print before sorting

  Arrays.sort(s, new Comparator<String>() {
    public int compare(String a1, String a2) {
        BigDecimal a = new BigDecimal(a1);
        BigDecimal b = new BigDecimal(a2);
        return a.compareTo(b);
    }
  });

  System.out.println("\n"+Arrays.toString(s)); //print after sorting
 }
}


Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.