1

我将以下字符串存储在trendList变量中。我做了一个排序,但数据没有正确排序。

ACLK_SCRN_200MHZ_DATAB_S0_P1:8应该在之前 ACLK_SCRN_200MHZ_DATAB_S0_P10:8

因为1 < 10,以此类推,其余的字符串。

问题:如何进行这种字母数字排序以获得正确的顺序?

我必须制作自己的功能吗?那会是什么样子?

List<String> trendList = new ArrayList<String>(80000);

Collections.sort(trendList);

ACLK_SCRN_200MHZ_DATAB_S0_P0:8
ACLK_SCRN_200MHZ_DATAB_S0_P10:8
ACLK_SCRN_200MHZ_DATAB_S0_P11:8
ACLK_SCRN_200MHZ_DATAB_S0_P12:8
ACLK_SCRN_200MHZ_DATAB_S0_P13:8
ACLK_SCRN_200MHZ_DATAB_S0_P14:8
ACLK_SCRN_200MHZ_DATAB_S0_P15:8
ACLK_SCRN_200MHZ_DATAB_S0_P1:8
ACLK_SCRN_200MHZ_DATAB_S0_P2:8
ACLK_SCRN_200MHZ_DATAB_S0_P3:8
ACLK_SCRN_200MHZ_DATAB_S0_P4:8
ACLK_SCRN_200MHZ_DATAB_S0_P5:8
ACLK_SCRN_200MHZ_DATAB_S0_P6:8
ACLK_SCRN_200MHZ_DATAB_S0_P7:8
ACLK_SCRN_200MHZ_DATAB_S0_P8:8
ACLK_SCRN_200MHZ_DATAB_S0_P9:8
ACLK_SCRN_200MHZ_DATAB_S1_P0:8
ACLK_SCRN_200MHZ_DATAB_S1_P10:8
ACLK_SCRN_200MHZ_DATAB_S1_P11:8
ACLK_SCRN_200MHZ_DATAB_S1_P12:8
ACLK_SCRN_200MHZ_DATAB_S1_P13:8
ACLK_SCRN_200MHZ_DATAB_S1_P14:8
ACLK_SCRN_200MHZ_DATAB_S1_P15:8
ACLK_SCRN_200MHZ_DATAB_S1_P1:8
ACLK_SCRN_200MHZ_DATAB_S1_P2:8
ACLK_SCRN_200MHZ_DATAB_S1_P3:8
ACLK_SCRN_200MHZ_DATAB_S1_P4:8
ACLK_SCRN_200MHZ_DATAB_S1_P5:8
MLC_C_SAMPLE
MLC_SAMPLE
SWR
TOUCHDOWN
TEST_REV
4

5 回答 5

1

您可以使用自己的 Comparator 执行此操作:

class TrendListComparator implements Comparator<String> {
     // retrieve the P and S
     final Pattern p = Pattern.compile(".*_S(\\d+)_P(\\d+).*");
     public int compare(String str1, String str2) {
         Matcher m1 = p.matcher(str1);
         Matcher m2 = p.matcher(str2);
         if (m1.matches() && m2.matches()) {
             Integer s1 = Integer.valueOf(m.group(1));
             Integer p1 = Integer.valueOf(m.group(2));
             Integer s2 = Integer.valueOf(m.group(1));
             Integer p2 = Integer.valueOf(m.group(2));
             // compare
             return s1.equals(s2) ? p1.compareTo(p2) : s1.compareTo(s2);
         } else {
             return str1.compareTo(str2); // standard sort if no P and S
         }
     }
}

Collections.sort(trendList, new TrendListComparator());

你可以在这里看到一个运行的例子:http: //ideone.com/AleOEy

您甚至可以只使用一个 Matcher 并在同一排序期间一直重复使用它:

class TrendListComparator implements Comparator<String> {
     // retrieve the P and S
     final Matcher m = Pattern.compile(".*_S(\\d+)_P(\\d+).*_S(\\d+)_P(\\d+).*").matcher("");
     public int compare(String str1, String str2) {
         if (m.reset(str1 + str2).matches()) {
             Integer s1 = Integer.valueOf(m.group(1));
             Integer p1 = Integer.valueOf(m.group(2));
             Integer s2 = Integer.valueOf(m.group(3));
             Integer p2 = Integer.valueOf(m.group(4));
             // compare
             return s1.equals(s2) ? p1.compareTo(p2) : s1.compareTo(s2);
         } else {
             return str1.compareTo(str2); // standard sort if no P and S
         }
     }
}

见:http: //ideone.com/EsfFPj

于 2013-02-28T19:47:09.867 回答
1

你得到这个结果是因为它只使用默认的 String.compareTo 比较字符串,它使用原始字符代码。':' 出现在 '0'-'9' 之后,因此它会在之后进行整理。

您需要自己提供Comparator并致电

Collections.sort(trendList, new CustomComparator());
于 2013-02-28T19:42:19.683 回答
0

您可以创建自己的实现Comparator<String>接口的类。在该compare方法中,您将需要解析字符串并从字符串的相关部分中提取需要按数字排序的数字。如果 s1 小于 s2,则该方法应返回一个小于 0 的数字,如果 s1 等于 s2 则返回 0,如果 s1 大于 s2 则返回大于 0 的数字。

public class MyTrendListComparator implements Comparator<String>
{
    public int compare(String s1, String s2)
    {
        // Parse and compare here.
    }
}

然后将比较器的实例传递给Collections.sort

Collections.sort(trendList, new MyTrendListComparator());
于 2013-02-28T19:44:53.957 回答
0

您可以将自定义比较器传递给Collections.sort()函数:

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

    @Override
    public int compare(String s1, String s2) {
        int sValue1 = s1.split(...) // split the strings to retrieve their values
        int sValue2 = // ...
        int pValue1 = // ...
        int pValue2 = // ...
        if (sValue1 > sValue2) { return 1; }
        if (sValue1 < sValue2) { return -1; }
        if (pValue1 > pValue2) { return 1; }
        if (pValue 1 < pValue2) { return -1; }
        return 0;
    }

});
于 2013-02-28T19:45:47.680 回答
0

这是代码:

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

public class CustomSorter {
   public static void main( String[] args ) {
      String[] data = {
         "ACLK_SCRN_200MHZ_DATAB_S0_P0:8",
         "ACLK_SCRN_200MHZ_DATAB_S0_P10:8",
         ...
         "ACLK_SCRN_200MHZ_DATAB_S1_P4:8",
         "ACLK_SCRN_200MHZ_DATAB_S1_P5:8",
      };
      List<String> trendList = Arrays.asList( data );
      Collections.sort( trendList, new Comparator< String >(){
         @Override public int compare( String o1, String o2 ){
            String[] p1 = o1.split( "_S\\d+_P" );
            String[] p2 = o2.split( "_S\\d+_P" );
            if( p1.length != 2 ) {
               throw new IllegalStateException("Unexpected item: '"+o1+"'");
            }
            if( p2.length != 2 ) {
               throw new IllegalStateException("Unexpected item: '"+o1+"'");
            }
            final int i1;
            try{
               i1 = Integer.parseInt(p1[1].substring(0,p1[1].indexOf(':')));
            } catch( NumberFormatException x ) {
               throw new IllegalStateException( "Unexpected item: '"+o1+"'");
            }
            final int i2;
            try{
               i2 = Integer.parseInt(p2[1].substring(0,p2[1].indexOf(':')));
            } catch( NumberFormatException x ) {
               throw new IllegalStateException("Unexpected item: '"+o2+"'");
            }
            int cmp = p1[0].compareTo( p2[0] );
            if( cmp == 0 ) {
               cmp = i1 - i2;
            }
            return cmp;
         }});
      for( String entry : trendList ) {
         System.out.println( entry );
      }
   }
}

和输出:

ACLK_SCRN_200MHZ_DATAB_S0_P0:8
ACLK_SCRN_200MHZ_DATAB_S0_P1:8
ACLK_SCRN_200MHZ_DATAB_S0_P2:8
ACLK_SCRN_200MHZ_DATAB_S0_P3:8
ACLK_SCRN_200MHZ_DATAB_S0_P4:8
ACLK_SCRN_200MHZ_DATAB_S0_P5:8
ACLK_SCRN_200MHZ_DATAB_S0_P6:8
ACLK_SCRN_200MHZ_DATAB_S0_P7:8
ACLK_SCRN_200MHZ_DATAB_S0_P8:8
ACLK_SCRN_200MHZ_DATAB_S0_P9:8
ACLK_SCRN_200MHZ_DATAB_S0_P10:8
ACLK_SCRN_200MHZ_DATAB_S0_P11:8
ACLK_SCRN_200MHZ_DATAB_S0_P12:8
ACLK_SCRN_200MHZ_DATAB_S0_P13:8
ACLK_SCRN_200MHZ_DATAB_S0_P14:8
ACLK_SCRN_200MHZ_DATAB_S0_P15:8
ACLK_SCRN_200MHZ_DATAB_S1_P0:8
ACLK_SCRN_200MHZ_DATAB_S1_P1:8
ACLK_SCRN_200MHZ_DATAB_S1_P2:8
ACLK_SCRN_200MHZ_DATAB_S1_P3:8
ACLK_SCRN_200MHZ_DATAB_S1_P4:8
ACLK_SCRN_200MHZ_DATAB_S1_P5:8
ACLK_SCRN_200MHZ_DATAB_S1_P10:8
ACLK_SCRN_200MHZ_DATAB_S1_P11:8
ACLK_SCRN_200MHZ_DATAB_S1_P12:8
ACLK_SCRN_200MHZ_DATAB_S1_P13:8
ACLK_SCRN_200MHZ_DATAB_S1_P14:8
ACLK_SCRN_200MHZ_DATAB_S1_P15:8
于 2013-02-28T19:54:40.650 回答