Java ArrayList的复杂排序

时间:2013-02-28 19:38:37

标签: java sorting alphanumeric

我在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

5 个答案:

答案 0 :(得分:1)

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

您需要提供自己的Comparator并致电

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

答案 1 :(得分:1)

您可以使用自己的比较器执行此操作:

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

您甚至可以只使用一个匹配器并在同一种类型中重复使用它:

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

答案 2 :(得分: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());

答案 3 :(得分: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;
    }

});

答案 4 :(得分: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