【问题标题】:Sorting alphanumeric strings java对字母数字字符串进行排序java
【发布时间】:2013-01-15 12:24:15
【问题描述】:

我有这个数组存储用户正在添加的一些 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);

            }

我的问题:

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

我希望您能帮助我了解最好的方法。

我想过创建一个列出 id 的数组然后排序,但我不知道如何在 java 中准确地对字母数字字符串进行排序。

【问题讨论】:

标签: java sorting


【解决方案1】:

只需在创建 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]

【讨论】:

  • 如果我们有超过 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] :(
  • 是的,我知道这会是个问题。但是为此,您可以创建自己的比较器实现,或者查看commons.apache.org,如果他们有什么可以帮助您的话。
  • 是的.. 但在走这条路之前,我会看看是否可以删除前缀“U”,然后对数字进行排序
【解决方案2】:

我决定使用@Abu 给出的想法,但我对其进行了调整:

  1. 我检查了用户尝试添加的 url 的 ID,
  2. 我删除了这个 id 中的字母后缀,然后我创建了一个 ArrayList 来存储每个 id 的数字部分。
  3. 我像@Abu 在他的回答中教我的那样对这个ArrayList 进行排序,然后我按照应该添加的顺序验证这个排序的ArrayList 中的每个ID..

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

【讨论】:

    【解决方案3】:

    我认为您的问题与此类似:

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

    您可以将字符串分解为纯字符串和数字字符串。 例如:abc123 将被拆分为“abc”和“123” 您可以将字母字符串与普通比较进行比较,然后对“123”这样的字符串进行排序,您有两种选择: 1:将其转换为Integer,然后进行比较 2:如果数字不在Integer范围内,可以逐字母比较。

    例如“123”与“133” 比较“1”和“1”=相等 比较“2”和“3”=更大,所以“123”

    选项 2 更准确,错误证明更少。

    【讨论】:

      【解决方案4】:

      创建自定义Comparator&lt;Map&lt;String,String&gt;&gt;

      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 之前,它对我不起作用:(
      • 是的,它使用字母数字顺序;显然你需要数字顺序。同样的方法也适用于此;您将需要进行更多编码以适当地处理 id 字符串。查看编辑后的代码。
      • 我应该在自定义 Comparator> 类中放什么?
      猜你喜欢
      • 2021-02-21
      • 2013-06-05
      • 2021-09-19
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多