user3016421
user3016421

Reputation: 119

How to Sort a String list which contains integer

I want to sort a list of String that also contains numbers.

For example, I have a list containing elements "1,2,3,4,5,11,12,21,22,31,32,A101,A102,A103,A104,B405".

If i use Collection.sort method means output is "1,11,12,2,21,22,3,31,32... ".

If i use Comparator function means it gives output as "1,2,3,4,5,11,12,21,22,31,32,A101... ".

But i need to display as

"A101,A102,A103,A104,B405,1,2,3,4,5,11,12,21,22,31,32"

Please any one give me a solution. Thanks in advance.

Upvotes: 1

Views: 1381

Answers (3)

53by97
53by97

Reputation: 425

Answer is present there in your question, just create two lists and sort them separately!

package com.kvvssut.misc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


public class SortStringThenNumber {

    public static void main(String[] args) {
        List<String> inputs = Arrays.asList(new String[]{"1","5","3","4","2","11","11","21","31","32","22","A101","A103","A104","B405","A102"});
        List<Object> result = sortStringThenNumber(inputs);

        for (Object sorted : result) {
            System.out.println(String.valueOf(sorted));
        }
    }

    private static List<Object> sortStringThenNumber(List<String> inputs) {

        List<Integer> numbers = new ArrayList<Integer>();
        List<String> strings = new ArrayList<String>();

        for (String input : inputs) {
            if (input.matches("-?\\d+")) {
                numbers.add(Integer.valueOf(input));
            } else {
                strings.add(input);
            }
        }
        inputs = null;

        Collections.sort(numbers);
        Collections.sort(strings);

        ArrayList<Object> all = new ArrayList<Object>();
        all.addAll(strings);
        all.addAll(numbers);

        return all;
    }

}

Upvotes: 0

wvdz
wvdz

Reputation: 16641

Implement your own comparator that tries to convert the objects to be compared to an integer, and if succesful, uses the compareTo of the Integer class, and otherwise uses the compareTo of the String class.

Like this:

public class MyComparator implements Comparator<String,String>
{
    public int compare(String s1, String s2)
   {
       try
       {
           int i1 = Integer.parseInt(s1);
           int i2 = Integer.parseInt(s2);
           return i1 - i2;
       }
       catch (NumberFormatException e)
       {
           return s1.compareTo(s2);
       }
   }
}

ArrayList<String> myList = (...);
Collections.sort(myList,new MyComparator());

As commented, this sorts like this 1,12,A102,A103. But wanted is: A102,A103,1,12. To do this we need to take care of situations where s1 is parsable as int and s2 is not and the other way around. I'm not sure if I got -1 and 1 right, so maybe they should be swapped.

public class MyComparator implements Comparator<String,String>
{
    public int compare(String s1, String s2)
   {
       Integer i1 = null
       Integer i2 = null
       try
       {
           i1 = Integer.parseInt(s1);
       }
       catch (NumberFormatException e) {}
       try
       {
           i2 = Integer.parseInt(s2);
       }
       catch (NumberFormatException e) {}
       if (i1 == null && i2 == null)
           return s1.compareTo(s2);
       if (i1 == null && i2 != null)
           return -1;
       if (i1 != null && i2 == null)
           return 1;
       return i1 - i2;
   }
}

Upvotes: 2

PalSivertsen
PalSivertsen

Reputation: 394

Create a new "holder" object for the strings and implement the Comparable interface. Override the "compareTo" method. That should do the trick ;)

Upvotes: 0

Related Questions