2014-03-02 131 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方法比较字符串。