Java中排序字母数字字符串

4

我有一个数组,存储用户添加的某些URL的后缀:

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

当我执行以下操作时:
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);

            }
我的问题:

我想通过传递另一个映射已排序数据的列表[U1,U2,U3,U4,U5,U6,U7,U8]来改变这个For条件。

我希望您能帮助我知道我应该如何做到最好。

我考虑创建一个列出ID并对其进行排序的数组,但我不知道如何在Java中准确地对字母数字字符串进行排序。


1
请查看TreeMap - Maxbester
4个回答

3

在创建完一个ArrayList后,只需使用Collections.sort()方法即可对列表进行排序:

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);

输出:

Before : [U2, U1, U5, U4, U3]
After : [U1, U2, U3, U4, U5]

3
如果我们有超过10个id,它就无法正常工作。例如: 原文:[U7, U2, U11, U3, U5, U0, U10, U4, U1, U9, U8, U6] 翻译后:[U0, U1, U10, U11, U2, U3, U4, U5, U6, U7, U8, U9] :( - periback2
1
这个问题在这里提到:http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html - periback2
是的,我知道这会成为一个问题。但是你可以创建自己的比较器实现,或者查看http://commons.apache.org/是否有可以帮助你的东西。 - Abubakkar
是的,但在这样做之前,我会尝试删除前缀“U”,然后对数字进行排序。 - periback2

3

我决定采用@Abu提出的想法,但我做了些改动:

  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.
            }
         }
    }
    

2
我认为你所问的类似于这个问题:

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

你可以将字符串分解为纯字符串和数字字符串。 例如:abc123会被分成“abc”和“123”。 你可以使用普通的比较方法比较字母字符串,然后对于像“123”这样的字符串进行排序,有两个选项: 1:将其转换为整数,然后进行比较 2:如果数字不适合整数范围,可以逐个字母进行比较。
例如,“123”与“133” 比较“1”和“1”=相等 比较“2”和“3”=大于,因此“123” < “133”。
选项2更精确,错误几率更小。

1
创建一个自定义的 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)); 
  }
}

然后在迭代之前使用Arrays.sort(urlAttachments, new IdComparator());。根据具体情况,您可以将此排序逻辑推入getUrlAttachments()中,并保持您现在发布的代码完全不变。


这个解决方案是否使用了Java的默认顺序?如果是的话,它会把U12放在U2之前,这对我来说行不通 :( - periback2
1
是的,它使用字母数字顺序;显然你需要数字顺序。对于那个问题,同样的方法也适用;你需要在代码中稍微多加一些处理id字符串的代码。请查看编辑后的代码。 - Marko Topolnik
我应该在自定义的Comparator<Map<String, String>>类中放什么? - periback2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接