2016-04-01 84 views
2

我有兩個比較器。一個用於按首字母排序的話(在排序僅用於元音字使用)接收比較器類型

public class FirstLetterComparator extends ComparatorType { 
@Override 
public int compare(String o1, String o2) { 
    String upperObject1 = o1.toUpperCase(); 
    String upperObject2 = o2.toUpperCase(); 

    return upperObject1.charAt(0) - upperObject2.charAt(0); 
    } 
} 

另一個用於通過長度/ vowelsCount COEF(在排序類用於所有字)

public class VowelColComparator extends ComparatorType { 
String vowelGroup = "AEIOUaeiou"; 

@Override 
public int compare(String o1, String o2) { 
    int vCount1 = getVowelCount(o1); 
    int vCount2 = getVowelCount(o2); 

    float compareCoef1 = o1.length()/vCount1; 
    float compareCoef2 = o2.length()/vCount2; 

    return (int)(compareCoef1 - compareCoef2); 
} 

public int getVowelCount(String word){ 
    int vowelCount = 0; 
    for (int i = 0; i < word.length(); i++){ 
     char ch = word.charAt(i); 
     for (int j = 0; j < vowelGroup.length(); j++){ 
      char v = vowelGroup.charAt(j); 
      if(ch == v) 
       vowelCount++; 
     } 
    } 
    return vowelCount; 
} 

而他們的超類分揀

public class ComparatorType implements Comparator<String> { 
@Override 
public int compare(String o1, String o2) { 
    return 0; 
    } 
} 

在排序類我有我的排序列表中的兩個類似的方法

public class SortWords { 

public static void sortVowelCol(String text, String regex){ 
    Scanner scanner = new Scanner(text); 

    List<String> words = new ArrayList<>(); 

    System.out.println(); 
    System.out.println("Task1:"); 
    while (scanner.hasNext()){ 
     String word = scanner.next(); 
     if(word.matches(regex)){ 
      words.add(word); 
     } 
    } 

    Collections.sort(words, new VowelColComparator()); 

    int lineCounter = 1; 

    System.out.println(); 
    System.out.println(); 
    System.out.println("Sorted Words:"); 
    lineCounter = 1; 
    for(String w : words){ 
     if(lineCounter == 12) { 
      System.out.print(w + "\n"); 
      lineCounter = 0; 
     } 
     else 
      System.out.print(w + " "); 
     lineCounter++; 
    } 

} 
public static void sortVowelWords(String text, String regex) { 
    Scanner scanner = new Scanner(text); 

    List<String> vowelWords = new ArrayList<>(); 

    System.out.println(); 
    System.out.println("Task2: "); 
    while(scanner.hasNext()){ 
     String word = scanner.next(); 
     if(word.matches(regex)){ 
      vowelWords.add(word); 
     } 
    } 

    Collections.sort(vowelWords, new FirstLetterComparator()); 

    System.out.println(); 
    System.out.println(); 
    System.out.println("Sorted List:"); 
    int lineCounter = 1; 
    for(String w : vowelWords){ 
     if(lineCounter == 12) { 
      System.out.print(w + "\n"); 
      lineCounter = 0; 
     } 
     else 
      System.out.print(w + " "); 
     lineCounter++; 
    } 
    } 
} 

主要類

public class Main { 

public static void main(String[] args) { 
    // write your code here 
    SingletonText.getInstance().parse(); 
    SingletonText.getInstance().print(); 
     SortWords.sortVowelWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*"); 
    SortWords.sortVowelCol(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*"); 
    } 
} 

的quesuion是如何讓只有一個方法,而不是在SortWords類中的兩個類似的方法?或者如何獲取Collections.sort參數的比較器類型?

回答

2

你需要重構二元函數的那樣:

public static void sortVowel(String text, String regex,Comparator comparator) { 
    Scanner scanner = new Scanner(text); 
    List<String> vowelWords = new ArrayList<>(); 

    System.out.println(); 
    System.out.println("Task2: "); 
    while(scanner.hasNext()){ 
     String word = scanner.next(); 
     if(word.matches(regex)){ 
      vowelWords.add(word); 
     } 
    } 

    Collections.sort(vowelWords, comparator); 

    System.out.println(); 
    System.out.println(); 
    System.out.println("Sorted List:"); 
    int lineCounter = 1; 
    for(String w : vowelWords){ 
     if(lineCounter == 12) { 
      System.out.print(w + "\n"); 
      lineCounter = 0; 
     } 
     else 
      System.out.print(w + " "); 
     lineCounter++; 
    } 
    } 
} 
3

您可以使用第三個參數來定義要使用的比較器。

public static void sort(String text, String regex, ComparatorType comp) { 
    // Code 
    Collections.sort(words, comp); 
    // Code 
} 
+1

傳遞一個int來定義這個方法應該做什麼真的很臭。相反,更好的方法是通過比較器本身。 – Tom

+0

謝謝!幫助了很多 –

+0

另一個有趣的方法是包含可用比較器的枚舉。然後可以將枚舉項傳遞給'sort'方法。缺點是,這將禁止「ComparatorType」的自己/匿名實現。 – Tom

0
public static void sort(String text, String regex, String sortType) { 

    Collections.sort(words, sorttype.equals("Vowel") ? new VowelColComparator() : new FirstLetterComparator()); 

    // Your code 

} 

然後我們可以這樣調用

SortWords.sort(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", "Vowel"); 
SortWords.sort(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", "firstletter"); 
0

所有VowelColComparator.getVowelCount首先可能會失敗,由於在給定字符串中沒有元音時除以零。當你在比較長和元音數量的比例,你可以做到以下幾點:

float compareCoef1 = o1.length()/(vCount1+1); 
float compareCoef2 = o2.length()/(vCount2+1); 

可以在ComparatorType類中使用工廠模式。即ComparatorType類將根據正則表達式決定使用哪個實例(比較器)。你可以添加儘可能多的比較器,只要你喜歡。

public abstract class ComparatorType implements Comparator<String> { 

    final public String vowelFirstLetterRegex = "^[A-Za-z].*"; 

    final public String vowelColRegex = "^[AEIOUaeiou].*]"; 


    public static ComparatorType getInstance(String regex) { 
     if (regex.equals(vowelColRegex)) 
      return new VowelColComparator(); 
     else if(regex.equals(vowelFirstLetterRegex)) 
      return new FirstLetterComparator(); 
     return null; 
    } 
} 

而且你SortWords類將有以下方法:

public static void sort(String text, String regex){ 
    Scanner scanner = new Scanner(text); 

    List<String> words = new ArrayList<>(); 

    System.out.println(); 
    System.out.println("Task1:"); 
    while (scanner.hasNext()){ 
     String word = scanner.next(); 
     if(word.matches(regex)){ 
      words.add(word); 
     } 
    } 

    Collections.sort(words, ComparatorType.getInstance(regex)); 

    int lineCounter = 1; 

    System.out.println(); 
    System.out.println(); 
    System.out.println("Sorted Words:"); 
    lineCounter = 1; 
    for(String w : words){ 
     if(lineCounter == 12) { 
      System.out.print(w + "\n"); 
      lineCounter = 0; 
     } 
     else 
      System.out.print(w + " "); 
     lineCounter++; 
    } 

} 
0

嗯,大家都說,你需要通過Comparator<String>作爲第三個參數,以你的方法:

sortVowelWords(String text, String regex, Comparator<String> cmp) { 
    //... 
} 

我我想提出一些對比較者本身的改進。使用lambda語法,他們可能會更容易寫:

static final Comparator<String> CMP_BY_FIRST_CHAR = 
    Comparator.comparing(s -> Character.toUpperCase(s.charAt(0))); 

static final Comparator<String> CMP_BY_VOWEL_COEF = 
    Comparator.comparing(s -> 1f * s.length()/s.replaceAll("[^AEIOUaeiou]+", "").length()); 

在第二比較中,我添加顯式的float妥善處理可能無限大的值。