-1

I have an ArrayList made up of strings. This ArrayList contains...

"60 Minutes" "120 Minutes" "30 Minutes"

If I use Collections.sort(ArrayList); it results in "120 Minutes" first. This is because the "1" in "120 is obviously smaller than the "3" in "30"

Is there a simple way I can sort this ArrayList so that it shows up as...

"30 Minutes" "60 Minutes" "120 Minutes"

Zack
  • 5,108
  • 4
  • 27
  • 39
  • 1
    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) – uthark Mar 26 '14 at 21:16

3 Answers3

7

Define your own class that implements Comparator<String>. In the compare method, extract the numbers out of the first part of the string arguments and compare them, returning -1, 0, or 1, if the first number is less than, equal to, or greater than, the second number.

Then you can pass an instance of your comparator (along with your ArrayList) to Collections.sort.

rgettman
  • 176,041
  • 30
  • 275
  • 357
  • I meant just a different built in method (If there is one). I'm trying to add as little code as possible to this one class. But this is a perfect answer for anyone else. Thanks. – Zack Mar 26 '14 at 18:03
  • This answer *is* as little code as possible. – aliteralmind Mar 26 '14 at 18:04
  • @Zack: Then remove the word minutes and sort by the raw minutes without the text. Then restore the text later. Seems pretty trivial – Engineer2021 Mar 26 '14 at 18:04
  • @Zack I don't think that there's a built-in method to parse strings of this particular format, extract the number expected in the first part of the string, and compare them. That's way too specific to be a built-in. – rgettman Mar 26 '14 at 18:05
  • @staticx I understand it is trivial. I am pulling these values from a database and I'm trying not to hard code anything in incase one day "60 Minutes" in the DB changes to "Sixty". Then my code with me splitting the strings will not work correctly. But thanks for the answers! – Zack Mar 26 '14 at 18:07
  • @Zack: Any type of comparator would have to recoded if that happens. Your interface changed. – Engineer2021 Mar 26 '14 at 18:10
  • @staticx Not with the way I am pulling the values. – Zack Mar 26 '14 at 18:14
  • @Zack: Your entire question just changed based on your "Sixty" comment. All our answers have just been rendered useless. It would have been nice to know this information to begin with. – aliteralmind Mar 26 '14 at 18:14
1

With Java 8 you could make it a one line operation with something like:

Collections.sort(list, comparing(s -> Integer.valueOf(s.split("\\s+")[0])));

However that still requires some messy logic to perform the comparison.

It would probably be cleaner and easier to maintain to create an ad-hoc class that holds the information in the form of an int and implements the Comparable interface.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • 1
    @aliteralmind http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing-java.util.function.Function- – assylias Mar 26 '14 at 18:12
0

Using @rgettman's idea, and assuming all strings are properly formatted as in your example input, the comparison itself could be something like this:

int spcIdx = s1.indexOf(" ");
int i1 = s1.substring(0, spcIdx);
String s1 = s1.substring(spcIdx + 1);

//Repeat for i1 and s2...

return  (((new Integer(i1)).compareTo(i2) * 10) + s1.compareTo(s2));
aliteralmind
  • 19,847
  • 17
  • 77
  • 108
  • OP just posted in a comment that 60 could become Sixty so this would fail if that happens. – Engineer2021 Mar 26 '14 at 18:11
  • Uhhh. So frustrating. There should be a significant punishment for questions that drastically change after many answers are posted. – aliteralmind Mar 26 '14 at 18:13
  • @staticx How do you plan to implement a logic that will work for `60 minutes` and `sixty minutes` at the same time without a lot more code?? – assylias Mar 26 '14 at 18:14
  • 2
    @assylias: Tell me about it.. that's my point to OP. The interface changed. – Engineer2021 Mar 26 '14 at 18:14
  • When a question completely changes like this, after many answers are posted, despite asking the OP many questions in an effort to make sure we're doing what they wanted, I think it should be an unspoken policy for all answer-ers to up-vote all other answers, down-vote the question, *and* vote to close it. – aliteralmind Mar 26 '14 at 18:17
  • @aliteralmind My Apologies – Zack Mar 26 '14 at 18:18