0

I am trying to sort an ArrayList<String>. The strings in the list look like this "abc 123 def 456" and I want to sort the list such that the string with the smallest last number comes first e.g. if the elements are

{"abc 123 def 456", "ghi 456 jkl 789", "mno 101 pqr 112"}

then I want the sorted list to have the third String first, then the first String, and then the second String.

{"mno 101 pqr 112", "abc 123 def 456","ghi 456 jkl 789"}

Just like this.

I tried to sort it using list.split(" "), Double.parseDouble(String)and Collections.sort(list), but I don't now how I could connect the remainder of my Strings correctly with the list of sorted numbers.

Edit:

String[] numbers = list.get(i).split(" ");
numberList.add(Integer.parseInt(numbers[3]));
Collections.sort(numberList);

Now I know how the numbers should be sorted, but I can't reconnect them with the rest of "their String".

7
  • Show us your best attempt. Don't use Double.parseDouble() to parse an integer. Commented Dec 12, 2015 at 16:53
  • Just sort by the last number, you are not force to separate the parts of the string so just don't do that. Why make your life harder? Commented Dec 12, 2015 at 16:54
  • @JBNizet Perhaps you could explain what is the downside of parsing an integer with parseDouble? Commented Dec 12, 2015 at 16:55
  • My actual String contains doubles not integers, that's why I wrote Double.parseDouble() here as well. @Peter Lawrey I want the Strings to be the same after sorting, just in an other order. Can I still sort by the last number? Commented Dec 12, 2015 at 16:58
  • Double.parseDouble() expects a decimal number, whereas you expect an integer. So it will happily return a value if what you're parsing happens to be a valid double, although it's supposed to accept only valid integers. For example, parseDouble() will happily parse "1.23e7", although that is clearly not what you expect, and you'd better have an exception, signalling the bug, if that's what you're actually parsing. If you expect an integer, parse an integer. Commented Dec 12, 2015 at 16:59

2 Answers 2

2

Simple solution with custom Comparator:

String[] arr = {"abc 123 def 456", "ghi 456 jkl 789", "mno 101 pqr 112"};

Arrays.sort(arr, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return getLastNum(o1) - getLastNum(o2);
    }

    private int getLastNum(String s) {
        String[] tokens = s.split(" ");
        return Double.parseDouble(tokens[tokens.length - 1]);
    }
});

Hope that this piece of code is self explanatory.

Sign up to request clarification or add additional context in comments.

Comments

0

If all of the will have the same format, then parse the last string of the result of String#split and compare those values.

list.sort((s1, s2) -> {
    String[] split1 = s1.split("\\s+");
    String[] split2 = s2.split("\\s+");
    return Double.compare(
        Double.parseDouble(split1[split1.length - 1]),
        Double.parseDouble(split2[split2.length - 1]);
});

Or as suggested by @JBNizet:

list.sort(Comparator.comparingDouble(s -> Double.parseDouble(s.substring(s.lastIndexOf(' ') + 1))));

6 Comments

Or, with Java 8: list.sort(Comparator.comparingDouble(s -> Double.parseDouble(s.substring(s.lastIndexOf(' ') + 1))));. Love those simple one-liners.
Your mixed up split1 and split2 in the answer: split2[split1.length - 1]
They're still in the wrong order. Your comparator sorts in reverse order. That's one of the benefits of Comparator.comparing(): you don't mess up with the order of the arguments, because you just have one.
I've misread the question, I (don't know why I) though OP was looking for inverse order.
I'm afraid I don't really understand your code. What is String#split ? And s1 and s2? Are those the Strings in the list?
|

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.