Sorting alphanumeric strings java
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.
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]
I decide to use the idea @Abu gave, but I adapted it:
- I check the ids of the urls the user is trying to add,
- I remove the alphabetic suffix in this id and then I create an
ArrayList
to store the numerical part of each id. -
I sort this
ArrayList
like @Abu taught me in his answer and then I verify for each id in this sortedArrayList
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. } } }
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.
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.