2017-10-10 118 views
-3

我有一个练习来输出用户输入的所有字符串升序。
当用户输入“quit”时程序应该停止。如何使用比较器与arraylist

import java.util.Scanner; 
    import java.util.ArrayList; 
    import java.util.Comparator; 
    import java.util.Collections; 
    public class Exercise2{ 
     public static void main (String[] args) { 
     ArrayList<String> list=new ArrayList<>(); 
     Scanner scanner = new Scanner(System.in); 
     String word="string"; 
     while(!word.equals("quit")){   // cycle will continue till string will contain a word "quit". 
      System.out.println("Please enter a string line. String can be whatever you want. After you enter a string please press Enter"); 
     word=scanner.nextLine(); 
     if(word.equals("quit")) 
     break; 
     list.add(word); 
     } 
     Collections.sort(list, new Comparator<String>(){ 
     public int compare(String o1, String o2){ 
       if(o1.length()>o2.length()){ 
        return 1; 
      }else{ 
        return o1.compareTo(o2); 
       } 
    } 

}); 

    System.out.println(list); 
} 
} 

任何人都可以解释为什么我的代码不工作?
我想用比较器来做。

+9

你是什么意思的“升序”?这与String的自然排序有何不同? (如果不是,你为什么要编写你自己的比较函数而不是使用自然顺序?) – azurefrog

+6

你能举一个你输入的例子吗?然后显示预期产出和实际得到的结果?这将帮助我们理解“不工作”的含义。 –

+1

您的比较函数首先检查一个字符串是否比另一个更长,如果不是,则使用比较字符串的自然顺序。不知道背后的逻辑应该是什么。我猜想这会打破比较方法的契约。 –

回答

3

您的比较器违反了compare的合同,该合同规定如果a> b则b < a也必须为真。然而,如果你通过“a1”和“b”,你会得到1,而如果你通过“b”和“a1”,你不会得到-1但是1。根据JavaDoc

摘录:

实现程序必须确保SGN(比较(X,Y))== -sgn(对比(Y,X))对于所有的x和y。

你需要是一致的,也就是说,如果你想比对长度第一,那么你需要做到这一点,只使用自然排序,当长度相等:

public int compare(String o1, String o2){ 
    //for Java 6 and below you could just do o1.length() - o2.length() 
    //as the return value doesn't have to be -1 or 1 but negative, 0 or positive 
    int result = Integer.compare(o1.length(), o2.length());/
    if(result == 0) { 
    result = o1.compareTo(o2); 
    } 
    return result; 
} 
+0

伙计们,我认为我的问题是我真的不明白collections.sort与比较器是如何工作的。请你能发送一个链接,详细介绍如何使用它? – Augustas

+0

@ugustas你应该得到关于如何在互联网上工作的大量信息,一个简单的搜索应该是足够的。但是,细节实际上并不重要。 _你的情况中的重要一点是:排序算法将采用列表中的2个元素,并将调用比较器来查看一个是否大于另一个,否则它会在必要时移动它们(但这对你的情况并不重要)。从逻辑的角度来看,哪些元素进行比较或以何种顺序并不重要,如果y y应始终为真。 – Thomas

0

两个选项,这取决于你想要什么。

1)如果只是想它按字母顺序:

Collections.sort(list); 

2)如果希望它由每个String的长度来分类:

编辑:加入子句如果String.length等于按更新的评论。

Collections.sort(list, new java.util.Comparator<String>() { 
      @Override 
      public int compare(String s1, String s2) { 
       if(s1.length() != s2.length()){ 
        return s1.length() - s2.length(); 
       } 
       return s1.compareTo(s2); 
      } 
     }); 
+1

你会如何按长度排序“abc”和“abg”?看到OP的评论:他想确保“abc”在“abg”之前。 – Thomas

+0

@Thomas我没有看到那是必要的。答案已更新。 – notyou