2014-03-02 74 views
3

我需要在一個類MinTester,使用比較對象從ArrayList集合計算「最小的」串 寫一個靜態方法:如何正確初始化比較器?

public static String min(ArrayList<String> list, Comparator<String> comp) 

我不能使用Collections類來計算最低。

這是我到目前爲止。

public class MinTester 
{ 
    public static String min(ArrayList<String> list, Comparator<String> comp) 
    { 
     String shortest = list.get(0); 

     for(String str : list) { 
      if (comp.compare(str, shortest) < 0) { 
       shortest = str; 
      } 
     } 
     return shortest; 
    } 
} 

我沒有從方法中得到任何錯誤,所以我嘗試在Main中測試它。 我試圖通過補償時出現此錯誤:變量補償可能沒有被初始化

public static void main(String[] args) 
{ 
    // TODO code application logic here 

    MinTester s = new MinTester(); 
    Comparator<String> comp; 
    ArrayList<String> list = new ArrayList<>(); 

    list.add("a"); 
    list.add("ab"); 
    list.add("abc"); 
    list.add("abcd"); 

    String a = s.min(list,comp);//Error: Variable comp may not have been initialized 

    System.out.println(a); 
} 

繼承人在那裏我遇到了我的問題。

我嘗試

Comparator<String> comp = new Comparator<>();//Error:Comparator is abstract, cannot be instantiated 
Comparator<String> comp = new MinTester();//Error: MinTester cannot be converted to Comparator<String> 

誰能告訴我來處理這個比較正確的方法是什麼?林不知道如果我只是試圖不正確地初始化它,或者如果我在我的MinTester類缺少的東西。

+0

你可以閱讀我關於這方面的文章(應該儘快更新)http://www.codeproject.com/Articles/703185/Comparator-and-Comparable-objects –

+0

你還沒有定義你所說的「最小」 。在代碼中暗示你的意思是「最短」,但是我懷疑這個定義比較複雜一點,就像「最短但是如果出現平局,根據字符排序順序排序(即按字母順序排列)」。一旦你知道了,執行'Comparator ''。 –

回答

4

你應該爲此寫一個實現Comparator<String>的類。一個快速的方法使用anonymous class

String a = s.min(list, new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     return s1.compareTo(s2); 
    } 
}); 

既然你需要比較基於字符串長度,只是改變比較邏輯的compare方法:

String a = s.min(list, new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     return (s1.length() > s2.length()) ? 1 : (s1.length() < s2.length()) ? -1 : 0; 
    } 
}); 

如果你碰巧使用Java 7,然後用Integer#compare

String a = s.min(list, new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     return Integer.compare(s1.length(), s2.length()); 
    } 
}); 

如果使用Java 8,你可以使用lambda表達式:

String a = s.min(list, (s1, s2) -> Integer.compare(s1.length(), s2.length())); 
+0

'比較器'是一個接口。它應該「實施」而不是延長。 –

+0

@KedarnathCalangutkar對,修正它。 –

+0

@LuiggiMendoza我試過了,我的輸出似乎是按字母順序排列的,而不是比較長度。如果我有'b'和'abc',a will = abc,因爲a在b之前。我會嘗試編輯它,但我不確定這個匿名方法是如何與我的MinTester類 – Reeggiie

-1

你不需要使用Comparator,至少不需要,除非你想修改字符串比較的自然順序。改用String類的compareTo()方法。

if (str.compareTo(shortest) < 0) { 
    shortest = str; 
} 

如果你要修改的自然順序,您可以創建一個實現Comparator接口的類,然後通過這個類的一個實例爲compare()方法。您也可以爲比較定義自己的邏輯。

public class StringDescComparator implements Comparator<String> { 
    @Override 
    public int compare(String str1, String str2) { 
     // return str1.compareTo(str2);  // For natural ordering 
     return -1 * str1.compareTo(str2); // For reversed ordering 
    } 
} 

然後可以使用上述類的實例在降爲了比較,使得:"b" < "a"

Comparator comp = new StringDescComparator(); 
+0

如果我正確理解問題,則需要使用「比較器」。 (這聽起來像是一個學校作業。) – Wyzard

+0

@Wyzard那是正確的 – Reeggiie

+0

哦!然後你可以在我的答案中使用Comparator類,返回語句爲'return str1.compareTo(str2);'保留自然順序 –

0

Comparator是一個接口;不同的類可以通過不同的方式實現不同類型的比較。你的方法採用Comparator的原因是,調用者可以選擇字符串應該如何比較。傳入一個Comparator,它進行詞法(也就是按字母順序)的比較,然後按詞法順序得到第一個字符串。傳入一個Comparator,查看字符串長度,然後您將得到最短的字符串。

由於String類已經實現了Comparable接口 - 一種兄弟姐妹來Comparator它使一個類定義自己的比較方法 - 這裏有一個方便的通用類,可以讓你使用任何Comparable通過Comparator接口:

public final class ComparableComparator<T extends Comparable<T>> implements Comparator<T> { 
    @Override 
    public int compare(final T a, final T b) { 
     return a.compareTo(b); 
    } 
} 

將其中的一個傳入您的方法,並使用String類自己的compareTo方法比較字符串。