0

I have an ArrayList with several objects per index. I want to sort this list alphanumerically by one object in particular. The object is "my_id" and the values for this object can look similar to: 1A, 10B, 11B, 2C, 205Z, etc.

I need to sort these to come out: 1A, 2C, 10B, 11B, 205Z. Where the numeric part is sorted first, then the alpha- part is sorted secondary. 1,2,3,4,5,... A,B,C,D,E,...

I checked out some alphanumeric string sorting that worked really well: http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/

Unfortunately I can only get that object to sort and I lose the other objects in my ArrayList as a consequence. I really need a sorting algorithm that can rearrange the ArrayList index's by the object of my choosing and not lose the other objects!

Is there a method to do this already out there? I've been unable to find one. I think it's useful to add that all the objects in my ArrayList are mapped strings: ArrayList<HashMap<String, String>>

[edit] I have my array: ArrayList<HashMap<String, String>> al

I then store the object:

String[] alphaNumericStringArray = new String[al.size()];
        for(int i = 0; i < al.size(); i++)
        {
            alphaNumericStringArray[i] = al.get(i).get("my_id");
        }

I now sort the string array:

// Sort the array now.
        Arrays.sort(alphaNumericStringArray, new AlphanumericSorting());

I then put the object back:

for(int i = 0; i < al.size(); i++)
        {
            HashMap<String, String> map = new HashMap<String, String>();
                map.put("my_id", alphaNumericStringArray[i]);
                // TODO, need to append the rest of the objects.
            al.set(i, map);
        }

I know what you're thinking, I'm not adding all the objects BACK when I re-map it. This is what I have currently, but what I want is a way to sort the whole list not just the one object "my_id". I want to rearrange the indexes so I don't have to re-map everything at the end.

10
  • 1
    Why do you lose objects? I do not see how you can lose objects by sorting a list? Commented Feb 26, 2015 at 15:38
  • 2
    "ArrayList with several objects per index", elaborate this... Commented Feb 26, 2015 at 15:41
  • 1
    could you post your code? maybe you're doing the sorting right but you're not saving your objects. Commented Feb 26, 2015 at 15:42
  • 1
    @waqaslam the op is refering to a list containing hashmaps Commented Feb 26, 2015 at 15:43
  • @UrielArvizu That is what I have in mind, but he failed to mention this important clue anywhere. However, it's still our assumption. :) Commented Feb 26, 2015 at 15:44

2 Answers 2

2

Running the main method:

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

public class Sorter {

    public static void main(String[] args) {

        List<String> unsorted = Arrays.asList("1A", "10B", "B", "753c", "Z", "M7", "32x", "11B", "2C", "205Z");

        Collections.sort(unsorted, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {

                if (o1.isEmpty())
                    return -1;

                if (o2.isEmpty())
                    return 1;

                String o1number = extractNumberPrefix(o1);

                String o2number = extractNumberPrefix(o2);

                if (o1number.isEmpty())
                    if (o2number.isEmpty())
                        return o1.compareTo(o2);
                    else return 1;

                if (o2number.isEmpty())
                    return -1;

                if (o1number.equals(o2number))
                    return o1.compareTo(o2);

                return Integer.parseInt(o1number) - Integer.parseInt(o2number);
            }

            private String extractNumberPrefix(String o1) {

                String result = "";
                for (int i = 0; i < o1.length(); i++) {
                    try {
                        Integer.parseInt(o1.substring(i, i + 1));
                        result += o1.substring(i, i + 1);
                    } catch (Exception e) {
                        break;
                    }
                }
                return result;
            }
        });

        System.out.println("sorted = " + unsorted);
    }
}

returns:

sorted = [1A, 2C, 10B, 11B, 32x, 205Z, 753c, B, M7, Z]
Sign up to request clarification or add additional context in comments.

2 Comments

I have the alphanumeric sorting down with a string array String[] but what I need is an ArrayList with mapped objects to sort based off an object of my choosing, i.e., "my_id" ex: al.get(i).get("my_id") <--
OP wants to sort HashMaps, by the value behind one key. The rest you seem to have correct.
0

After careful reconstruction of the Comparator and all the comments I finally figured out how to do this.

Question: To reiterate what my goal is, as well as the solution. I have an ArrayList<HashMap<String, String>>. I want to sort the ArrayList by one object in the HashMap. My HashMap has more than 1 object in it so I want to retain the entire index of the Array. I also want to sort alphanumerically where numeric values are the first to be sorted, than I sort alphabetically. i.e., 1,2,3,4,... A,B,C,D,...

References: http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/

TL;DR Solution: In my custom Comparator function public int compare(object firstObj, Object secondObj) I needed to change the String values to HashMap object references/values. Here the KEY_ID is the object that I wanted to sort by. Once I did this I used Collections.sort to sort by the HashMap comparator rather than the Arrays.sort (Collections handles ArrayList/HashMaps).

Code Solution:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

/** 
 * DOCUMENTATION: 
 * http://sanjaal.com/java/206/java-data-structure/alphanumeric-string-sorting-in-java-implementation/ 
 **/

@SuppressWarnings({"rawtypes", "unchecked"})
public class AlphanumericSorting implements Comparator 
{
    public int compare(Object firstObjToCompare, Object secondObjToCompare) 
    {
        String firstString  = ((HashMap<String,String>) firstObjToCompare).get("KEY_ID");
        String secondString = ((HashMap<String,String>) secondObjToCompare).get("KEY_ID");

        //String firstString    = firstObjToCompare.toString();
        //String secondString = secondObjToCompare.toString();

        if (secondString == null || firstString == null) 
        {
            return 0;
        }

        int lengthFirstStr  = firstString.length();
        int lengthSecondStr = secondString.length();

        int index1 = 0;
        int index2 = 0;

        while(index1 < lengthFirstStr && index2 < lengthSecondStr) 
        {
            char ch1 = firstString.charAt(index1);
            char ch2 = secondString.charAt(index2);

            char[] space1 = new char[lengthFirstStr];
            char[] space2 = new char[lengthSecondStr];

            int loc1 = 0;
            int loc2 = 0;

            do 
            {
                space1[loc1++] = ch1;
                index1++;

                if (index1 < lengthFirstStr) 
                {
                    ch1 = firstString.charAt(index1);
                } 
                else 
                {
                    break;
                }
            } 
            while (Character.isDigit(ch1) == Character.isDigit(space1[0]));

            do 
            {
                space2[loc2++] = ch2;
                index2++;

                if (index2 < lengthSecondStr) 
                {
                    ch2 = secondString.charAt(index2);
                } else 
                {
                    break;
                }
            } 
            while (Character.isDigit(ch2) == Character.isDigit(space2[0]));

            String str1 = new String(space1);
            String str2 = new String(space2);

            int result;

            if (Character.isDigit(space1[0]) && Character.isDigit(space2[0])) 
            {
                Integer firstNumberToCompare    = new Integer(Integer.parseInt(str1.trim()));
                Integer secondNumberToCompare   = new Integer(Integer.parseInt(str2.trim()));

                result = firstNumberToCompare.compareTo(secondNumberToCompare);
            } 
            else 
            {
                result = str1.compareTo(str2);
            }

            if (result != 0) 
            {
                return result;
            }
        }

        return lengthFirstStr - lengthSecondStr;
    }

    /**
     * ALPHANUMERIC SORTING
     */
    public static ArrayList<HashMap<String, String>> sortArrayList(ArrayList<HashMap<String, String>> al)
    {
        Collections.sort(al, new AlphanumericSorting());

        return al;
    }
}

To return the sorted ArrayList:

myArrayList = AlphanumericSorting.sortArrayList(myArrayList);

Where,

ArrayList<HashMap<String, String>> myArrayList;

Comments

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.