1

I'm just trying to see if there is an easy way to sort a list of String objects. Problem I'm facing right now is that the Collections.sort(...) method is not working for me.

This is my original list, which for my requirement purposes is sorted:

    List<String> values = new ArrayList<String>();


    values.add("section_1");
    values.add("section_2");
    values.add("section_3");
    values.add("section_4");
    values.add("section_5");
    values.add("section_6");
    values.add("section_7");
    values.add("section_8");
    values.add("section_9");
    values.add("section_10");
    values.add("section_11");
    values.add("section_12");
    values.add("section_13");

And after doing Collections.sort(values), the order is now broken:

section_1
section_10
section_11 
section_12
section_13
section_2
section_3
section_4
section_5
section_6
section_7
section_8
section_9

Is this behavior because of the lexicographical ordering used in Collections.sort(...) ? Is there an easier way to make this sort work the way I want it to?

Thanks in advance.

Marquinio
  • 4,601
  • 13
  • 45
  • 68
  • possible duplicate of [Natural sort order string comparison in Java - is one built in?](http://stackoverflow.com/questions/1262239/natural-sort-order-string-comparison-in-java-is-one-built-in) – Shaggy Frog Jun 04 '12 at 19:19

3 Answers3

9

Is this behavior because of the lexicographical ordering used in Collections.sort(...) ?

Absolutely. You've sorted the strings according to the natural ordering.

Is there an easier way to make this sort work the way I want it to?

Create a class implementing Comparator<String> which expresses the comparison you want to use, and pass that as a second argument to Collections.sort. You'll have to write the logic yourself though (or find a third-party library to do so). I don't think there's anything in the standard libraries to do this. (You'll want to consider case-sensitivity and possibly all kinds of other things.)

Of course, if you could change your data to be section_01, section_02 etc, that would mean you could just use the natural sort order...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

You'll need to use a custom comparator that extracts the numerical part of the Strings, transform them into Integer instances, and compare those Integers:

public class SectionComparator implements Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        Integer i1 = Integer.valueOf(s1.substring(s1.indexOf('_') + 1));
        Integer i2 = Integer.valueOf(s1.substring(s2.indexOf('_') + 1));
        return i1.compareTo(i2),
    }
}

But instead of using Strings to represent sections, you could also use Section objects, which would have a number attribute, a toString() method, and a natural ordering using the number attribute.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

see also this post

you need to use The Alphanum Algorithm

Others previously suggested to implement Comparator. here's an implementation

Good Luck!

Community
  • 1
  • 1
baby boom
  • 158
  • 2
  • 11