views:

112

answers:

6

How can I sort an array first by length, then alphabetically?

I have a list of things with numbers on them, and I am currently getting:

Something1 Something10 Something2 Something3

Whereas I want to get:

Something1 Something2 Something3 Something10

+4  A: 

Create a Comparator which compares by length first and if the lengths are the same, uses the String.compareTo().

Peter Lawrey
Also note the existence of `compareToIgnoreCase()`.
Mark Peters
A: 

Implement your own class that contains this array and that class should implement Comparable, and the CompareTo() method, this way you can create an array of something and say Arrays.sort(something) and it will sort it against your compareTo method, if you need more info let me know. You can also just implement a comparator method and send it to Arrays.Sort but I haven't done java in a while so I can't remember how to call it exactly.

Jesus Ramos
+4  A: 

I'm assuming it's not a homework question

public class MyComparator implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {  
      if (o1.length() > o2.length()) {
         return 1;
      } else if (o1.length() < o2.length()) {
         return -1;
      } else { 
         return o1.compareTo(o2);
      }
    }
}

Then use:

Collection.sort(yourList, new MyComparator());
Samuel_xL
Comparator requires int compareTo(Obj o), not compare(Object o1, Object o2). This code is close though.
Starkey
@Starkey: That's Comparable. This is Comparator. You were close though.
Mark Peters
Thanks, I just needed to sort some file names that had numbers in them really quickly and rename them.I had them in an Array so I had to convert it to a Collection, but this worked for my purpose. Thanks!
Brian
@Mark Peters What about Comparatee?
Jeff Davis
+2  A: 

Have a look at the answers for http://stackoverflow.com/questions/104599/sort-on-a-string-that-may-contain-a-number if what you really want is a sort that understands the number part.

Paul Tomblin
A: 

Sorting first by length and then lexically will work ONLY if the string prefixes (i.e. the part before the number) is the same length in all cases. I believe you may really want to write a comparator that separates the string and numeric parts and sorts alphabetically on the string and numerically on the number part.

Jim Garrison
A: 

Define a class to hold your item in. Seems like you want it to be a String.

For that class, you need to define the Comparable interface and put the logic to compare in its abstract method.

int compareTo(T o)  

For example:

class MyString extends String
{
  @Override
  int compareTo(Object obj)
  {
    // put your logic in here. 
    // Return -1 if this is "less than" obj. 
    // Return 0 if this is equal to obj
    // Return 1 if this is "greater than" obj.

    // Test length first
    if (length() < obj.length())
      return -1;
    if (length() > obj.length())
      return 1;

    // Lengths are the same, use the alphabetical compare defined by String already
    return super.compareTo(obj);
   }
}

Disclaimer, I didn't actually test this code, but it should be close to what you want.

Starkey