4

I have this array storing the suffix of some URLs the user is adding:

[U2, U3, U1, U5, U8, U4, U7, U6]

When I do this:

for (Map<String, String> map : getUrlAttachments()) {
            String tmpId = map.get("id"); //it receives the U2, in the 1st iteration, then U3, then U1,...
            if (tmpId.charAt(0) == 'U') {
                tmpId.charAt(1);//2, then 3, then 1,...
                String url = map.get("url");
                String description = map.get("description");
                URLAttachment attachment;
                String cleanup = map.get("cleanup");
                if (cleanup == null && url != null && description != null) {
                    attachment = new URLAttachmentImpl();
                    attachment.setOwnerClass(FileUploadOwnerClass.Event.toString());
                    attachment.setUrl(url);
                    attachment.setDescription(description);
                    attachment.setOwnerId(auctionHeaderID);
                    attachment.setUrlAttachmentType(URLAttachmentTypeEnum.EVENT_ATTACHMENT);
                    attachment.setDateAdded(new Date());
                    urlBPO.save(attachment);

            }

My problem:

I want to change this For condition by passing another list mapping the data sorted like [U1, U2, U3, U4, U5, U6, U7, U8].

I'd like your help to know what's the best way I could do this.

I thought about creating an array listing the ids and then sort then, but I don't know how exactly to sort alphanumeric strings in java.

1
  • 1
    Have a look to TreeMap. Commented Jan 15, 2013 at 12:25

4 Answers 4

3

Just use Collections.sort() method after creating an ArrayList of your values like this:

ArrayList<String> a = new ArrayList<String>();
a.add("U2");
a.add("U1");
a.add("U5");
a.add("U4");
a.add("U3");
System.out.println("Before : "+a);
Collections.sort(a);
System.out.println("After : "+a);

Output :

Before : [U2, U1, U5, U4, U3]
After : [U1, U2, U3, U4, U5]
Sign up to request clarification or add additional context in comments.

4 Comments

it doesn't work if we have more than 10 ids.. ex: Before: [U7, U2, U11, U3, U5, U0, U10, U4, U1, U9, U8, U6] After: [U0, U1, U10, U11, U2, U3, U4, U5, U6, U7, U8, U9] :(
this problem was mentioned here: weblogs.java.net/blog/skelvin/archive/2006/01/…
Yeah I knew it would be a problem. But for that you can create your own implementation of a comparator or have a look at commons.apache.org if they have something that can help you.
yes.. but before going this way I'll see if I can remove the prefix 'U' and then sort the numbers
3

I decide to use the idea @Abu gave, but I adapted it:

  1. I check the ids of the urls the user is trying to add,
  2. I remove the alphabetic suffix in this id and then I create an ArrayList to store the numerical part of each id.
  3. I sort this ArrayList like @Abu taught me in his answer and then I verify for each id in this sorted ArrayList in the sequence it should be added..

    ArrayList <Integer> urlSorted = new ArrayList<Integer>();
    //sort the url ids
    for (Map<String, String> map : getUrlAttachments()) {
        String tmpId = map.get("id");
        if (tmpId.charAt(0) == 'U') {
            //gets the id, removing the prefix 'U'
            urlSorted.add( Integer.valueOf(tmpId.substring(1)));
        }
    }
    //sort the urlIds to check the sequence they must be added
    Collections.sort(urlSorted);
    //checks for each url id, compares if it's on the natural order of sorting to be added.
    for(Integer urlId: urlSorted) {
        for (Map<String, String> map : getUrlAttachments()) {
            String sortedId = "U"+urlId;
            String tmpId = map.get("id");
            //compare the ids to add the 1, then 2, then 3...
            if (map.get("id").equals(sortedId)) {
                        //code to save according to the sorted ids.
            }
         }
    }
    

Comments

2

I think what you are asking is similar to this one :

http://www.davekoelle.com/alphanum.html

You can break string into pure string and numeric string. for e.g: abc123 would be split into "abc" and "123" You can compare alphabetic string with normal comparison and then to sort "123" such kind of strings, you have two options: 1: Convert it into Integer and then compare 2: If number does not fit in Integer range, you can compare letter by letter.

for eg "123" vs "133" compare "1" and "1" = equal Compare "2" and "3" = greater so "123" < "133".

Option 2 is more accurate and less error proof.

Comments

1

Create a custom Comparator<Map<String,String>>:

public class IdComparator implements Comparator<Map<String,String>> {
  public int compare(Map<String,String> left, Map<String,String> right) {
    return orderKey(left).compareTo(orderKey(right));
  }
  static Integer orderKey(Map<String,String> m) { 
    return Integer.parseInt(m.get("id").substring(1)); 
  }
}

and then use Arrays.sort(urlAttachments, new IdComparator()); prior to iterating over it. Depending on details, you may push this sorting logic into getUrlAttachments() and keep the code you have posted exactly as it is now.

3 Comments

does this solution uses java's default order? if so, it will put U12 before U2, and it won't work for me :(
Yes, it uses alphanumeric order; apparently you needed numeric order instead. The same approach will apply for that, too; there will be slightly more coding on your part to process the id strings appropriately. See edited code.
what should I put in the custom Comparator<Map<String, String>> class?

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.