Megid
Megid

Reputation: 105

Sorting an Integer list as if it were a String list in Java

I have a simple array of integers and I want to sort them but by String rules

Example: {1, 7, 43, 15, 2, 12} -> {1, 12, 15, 2, 43, 7}

I looked around and found Integer.toString(int) and String.valueOf(int) but that requires to make a new String array and convert them individually and sort it and convert it back to Integer and reassign it. Also, a Comparator I presume wouldn't be much different.

So are there more ways to do this?

Upvotes: 3

Views: 131

Answers (5)

just another way, this time using the lambda power of java8

List<Integer> l = Arrays.asList(1, 7, 43, 15, 2, 12);
l.sort((x, y) -> x.toString().compareTo(y.toString()));
System.out.println(l);

Output:

[1, 12, 15, 2, 43, 7]

Upvotes: 1

dumbPotato21
dumbPotato21

Reputation: 5695

I'll still go with this

List<Integer> list = Arrays.asList(1, 7, 43, 15, 2, 12);
List<Integer> orderedList= list.stream()
                               .map(String::valueOf)
                               .sorted()
                               .map(Integer::parseInt)
                               .collect(Collectors.toList());

Upvotes: 2

GhostCat
GhostCat

Reputation: 140427

The two straight forward choices are:

  • creating a List<String> from your List<Integer>, to then sort that String list, and turn it back into an Integer list in the end.
  • using a custom comparator

The major difference: when you create list of strings initially, then you have to do that transformation Integer -> String ... exactly once per input number.

When you do that within the comparator, then you are doing it probably much more often! As you will be using a Comparator<Integer, Integer> ... which will always need to turn both arguments into Strings. Or do the relatively expensive math to determine the "length" of the input numbers.

Beyond that: unless we are talking about code that works on millions of numbers; or that is called a thousands of time each minute ... worrying about performance is simply wrong. Worry about the readability of your code; and the effort required to maintain it in the future.

Finally: if you see this as a challenge how to solve this problem using "interesting" ways; one other solution: you could use some Pair<String, Integer> class; with the String generated from the Integer number. Now you put those into a List, and use a comparator to sort on the String part of the Pair. Then you don't need another conversion; you simply walk the pairs, and you fetch the Integer numbers from each pair. But again, that is micro-performance-management and is "for the fun" only.

Upvotes: 4

Arnaud
Arnaud

Reputation: 17524

Here is an example using a custom Comparator, based on the String representation of the integers :

Integer[] intArray = { 1, 7, 43, 15, 2, 12 };

Comparator<Integer> comparator = new Comparator<Integer>() {

    @Override
    public int compare(final Integer o1, final Integer o2) {

        return String.valueOf(o1).compareTo(String.valueOf(o2));
    }

};

Arrays.sort(intArray, comparator);

System.out.println(Arrays.toString(intArray));

Upvotes: 3

user2390182
user2390182

Reputation: 73450

You can use a custom Comparator. You can keep it generic if you w ant to use it for other types as well:

class StringComparator<T> implements Comparator<T> {
  @Override
  public int compare(T first, T second) {
    // compare String representations
    return first.toString().compareTo(second.toString());
  }
}

Then, you can sort:

Integer[] a = {1; 2; 3; 11; 22}
Arrays.sort(a, new StringComparator<Integer>());

Upvotes: 0

Related Questions