2015-04-29 46 views
1

这里是我到目前为止的代码:如何创建自定义比较排序的编号系统

package Demo; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 

public class Demo { 

    public static void main(String[] args) { 

     ArrayList<String> list = new ArrayList<String>(); 

     list.add("3.3.x"); 
     list.add("1.2.x"); 
     list.add("2.3.x"); 

     VersionComparator x = new VersionComparator(); 

     Collections.sort(list, x); 

     for(String str : list) 
      System.out.println(str); 

    } 

    static class VersionComparator implements Comparator { 
     public int compare(String str1, String str2) { 

      String firstNumberStringOne = str1.split(".")[0]; 
      String firstNumberStringTwo = str2.split(".")[0]; 
      String secondNumberStringOne = str1.split(".")[1]; 
      String secondNumberStringTwo = str2.split(".")[1]; 

      return; 
     } 

     @Override 
     public int compare(Object o1, Object o2) { 
      // TODO Auto-generated method stub 
      return 0; 
     } 
    } 
} 

我想通过月经前出现的第一个号在我的列表中的项目进行排序。如果这两个数字相等,则转到第二个数字并比较这些数字。如果平等,只要归还他们。

我不确定如何使用比较器。我试图实现它,编译器抱怨说我需要在第二个比较方法中添加override。我也不知道如何进行比较,如何返回。我明白,如果它相等,那么它返回一个0并且它小于那么它返回一个-1并且大于1.但是在编码方面,我失去了程序如何知道如何排序它。

+1

'分裂( “”)'不好看。请阅读以下其中一项:http://stackoverflow.com/q/14833008/1393766 http://stackoverflow.com/q/7935858/1393766 http://stackoverflow.com/q/3387622/1393766 http:// stackoverflow。 com/q/2755945/1393766 – Pshemo

回答

0

有你的代码几个问题:

  1. 您正在使用原始类型,因此在

    class VersionComparator implements Comparator 
    

    比较Comparator<T>将尝试使用Object as T这意味着它的声明为compare(T t1, T t2)的比较方法将是compare(Object t1, Object o2)。所以,如果你想比较Strings化妆比较弦乐像

    class VersionComparator implements Comparator<String> 
    

    现在就知道TString所以比较方法会是这个样子 compare(Object t1, Object o2){..}

  2. 当你调用split(".")你是不是分裂上的点,但在任何字符(因为split是使用正则表达式,而在正则表达式.表示在线分离器\n\r旁任何字符)。因为在开始时你会得到一些空的元素,然后将被清除,因为split删除空的尾随元素。更多的信息在这里:https://stackoverflow.com/a/21790319/1393766

    要解决此问题,您需要使用"\\."来转义.

这应该涵盖代码中的主要问题。但是,如果你想创建一个很好的解决方案,那么考虑避免排序Strings,而是你自己的Version类的实例。
这种方法的优点在于,每次您想比较两个字符串(可能会很昂贵)时,您不必将字符串解析为int,但可以将解析版本"1.2.3"存储为数组[1, 2, 3]并重新使用它需要的时候。
另外Version类可以实现Comparable<Vector>来提供默认比较方法。

所以,你的代码可以看起来更像:

class Version implements Comparable<Version> { 

    private String versionStr; 
    private int[] arr; 

    public String getVersionStr() { return versionStr; } 

    @Override public String toString() { return versionStr; } 

    @Override 
    public int compareTo(Version o) { 

     int result = Integer.compare(arr[0], o.arr[0]); 

     if (result != 0) 
      return result; 

     return Integer.compare(arr[1], o.arr[1]); 
    } 

    public Version(String versionStr) { 
     this.versionStr = versionStr; 
     this.arr = Stream.of(versionStr.split("\\.")) 
       .limit(2)//get only two first elements 
       .mapToInt(Integer::parseInt)//convert String to int 
       .toArray();//return array of integers 
    } 

} 

class Demo { 

    public static void main(String[] args) { 

     List<Version> list = new ArrayList<Version>(); 

     list.add(new Version("3.3.x")); 
     list.add(new Version("1.2.x")); 
     list.add(new Version("1.11.x")); 
     list.add(new Version("2.3.x")); 

     Collections.sort(list); 

     for (Version str : list) 
      System.out.println(str); 
    } 
} 
2

VersionComparator类正在实施Comparator接口,其中,所述方法compare将2个Object!而非2个String S的原始形式。

通过供给String作为一种类型的参数实现的接口。然后编译器会识别出你的compare方法,将String作为接口的正确实现的参数。您不需要compare方法采取Object s。

static class VersionComparator implements Comparator<String> { 

你当然需要实现在compare method比较逻辑,返回一个int小于0,0,或大于0,如果str1根据比较小于,等于或大于str2您自定义排序顺序。

0
public static void main(String[] args) { 
    ArrayList<String> list = new ArrayList<String>(); 
    list.add("3.3.x"); 
    list.add("1.2.x"); 
    list.add("1.11.x"); 
    list.add("1.1.x"); 
    list.add("2.3.x"); 

    Collections.sort(list, new VersionComparator()); 

    for(String str : list) 
     System.out.println(str); 

} 

static class VersionComparator implements Comparator<String> { 
    //Temporary Cache Map to hold Split String value. String as Key and Split String array as value is this in this map. 
    Map<String, String[]> mCacheMap = new HashMap<>(); 

    @Override 
    public int compare(String string1, String string2) { 

     if(!mCacheMap.containsKey(string1)){ 
      //Put Split String of string1 to map if it does not contain it. 
      mCacheMap.put(string1, string1.split("\\.")); 
     } 
     if(!mCacheMap.containsKey(string2)){ 
      //Put Split String of string2 to map if it does not contain it. 
      mCacheMap.put(string2, string2.split("\\.")); 
     } 
     //Get First Digit of first string1 from Map 
     Integer string1Val1 = Integer.valueOf(mCacheMap.get(string1)[0]); 
     //Get First Digit of second string2 from Map    
     Integer string2Val1 = Integer.valueOf(mCacheMap.get(string2)[0]); 

     //Compare Both Digit. compareTo Method return a negative integer, zero, or a positive integer as first Integer value is less than, equal to, or greater than the seconf Integer value. 
     int cmp = string1Val1.compareTo(string2Val1); 

     if(cmp != 0){ 
      return cmp; 
     }else { 
      //If First digit of both string is same compare second digit. 
      Integer string1Val2 = Integer.valueOf(mCacheMap.get(string1)[1]); 
      Integer string2Val2 = Integer.valueOf(mCacheMap.get(string2)[1]); 
      return string1Val2.compareTo(string2Val2); 
     } 

    } 
} 

结果:

1.1.x 
1.2.x 
1.11.x 
2.3.x 
3.3.x 
+0

我会很快发布更新。 –

+0

@Pshemo你可以请检阅我更新的答案。 –

+0

效果更好。现在你只需要解释OP他/她的方法出了什么问题,以及你的方法为什么/如何工作。 – Pshemo

相关问题