在Java中,如何快速排序排序字段为多层深度的对象的ArrayList?

基本上,我有一个名为“Employees”的Container类,其中包含一个ArrayList。 此ArrayList包含“Employee”对象,后者又包含“EmployeeData”对象,而这些对象又包含String对象,例如“first”或“last”(这是员工姓名)。

这是ArrayList结构的图表:

ArrayList[Employee] emps ==> 1:Many ==> Employee emp Employee emp ==> 1:1 ==> EmployeeData data EmployeeData data ==> 1:2 ==> String last // A string that contains employee's last name. 

我将如何在ArrayList上执行快速排序,以便其中的“Employee”对象基于String对象“last”按字母顺序排列? 看起来有点复杂!


这是我class级的基本设计:

 class Employees{ //data: private ArrayList emps = new ArrayList(); //Some constructors go here //Methods to add, remove, toString, etc, go here public /*output a sorted ArrayList?*/ sort(){ // Some kind of "quicksort" in here to modify or create a new ArrayList sorted by employee's las name... } } class Employee{ //data: EmployeeData data; // Some methods to construct and modify EmployeeData data. } class EmployeeData{ //data: String first, last; // I wish to sort with "last". How do you do it? double payrate, hours; //...methods... } 

如您所见,这些是课程。 我不知道如何在“Employees”类中实现“sort”,以便它通过“EmployeeData”类的“last”变量对ArrayList进行排序。

最佳实践是在这种情况下将排序逻辑封装在存储在ArrayList,Employee中的类中。 通过创建compareTo(Employee)方法实现Comparable。

 import java.util.*; public class Employee implements Comparable { public EmployeeData Data; public Employee(String first, String last) { Data = new EmployeeData(first, last); } public int compareTo(Employee other) { return Data.Last.compareTo(other.Data.Last); } public String toString() { return Data.First + " " + Data.Last; } public static void main(String[] args) throws java.io.IOException { ArrayList list = new ArrayList(); list.add(new Employee("Andy", "Smith")); list.add(new Employee("John", "Williams")); list.add(new Employee("Bob", "Jones")); list.add(new Employee("Abraham", "Abrams")); Collections.sort(list); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.in.read(); } } public class EmployeeData { public String First; public String Last; public EmployeeData(String first, String last) { First = first; Last = last; } } 

输出:

 Abraham Abrams Bob Jones Andy Smith John Williams 

你可以做一个比较器,如:

 public class MyComparator implements Comparator { public int compare(Employee e1, Employee e2) { return e1.getData().getLast().compareTo(e2.getData().getLast()); } } 

然后用它来排序列表。

 Collections.sort(myList, new MyComparator()); 

或者,您可以使用TreeSet对使用此比较器的插入进行排序,或者使Employee成为可比较的对象,以使用Collections或SortedSet进行排序。

 public class Employee implements Comperable { ... public int compareTo(Employee e) { return this.getData().getLast().compareTo(e.getData().getLast()); } ... } 

定义Employee implements Comparable

compareTo方法中,深入了解图层并比较所需的字符串。 然后您可以使用Collections.sort() ,或者您可以将数据存储在自然排序的SortedSet

Peter DeWeese和其他人给了你非常好的答案。 您可以使用

 Collections.sort(myList, new MyComparator()); 

使用您定义的Comparator对myList进行排序。 <===这到底意味着什么?

在Java中,如果某些东西实现了Comparable (java.lang.comparable),那么您可以为元素定义一个顺序。 您似乎知道Java Generics是什么,因为您使用它们将ArrayList声明为类型。 这很棒,因为您可以将Employee对象存储到ArrayList中的每个条目中。 到现在为止还挺好?

但是,如果要对对象进行排序,首先必须定义顺序。 由于对象可以具有各种属性,因此我可能希望按照耳朵大小对员工进行排序。 在这种情况下,我只是告诉Java我的类实现了Comparable。 使用generics,我必须指定它实现Comparable ,因为我正在定义我的Employee对象(peons,minions等)的订单。

Peter DeWeese提到:

  public int compareTo(Employee e) { return this.getData().getLast().compareTo(e.getData().getLast()); } 

和Jason Goemaat提到:

 public int compareTo(Employee other) { return Data.Last.compareTo(other.Data.Last); } 

这到底意味着什么? 如果我说我的类实现了Comparable,那么我需要定义一个compareTo函数。 (接口是需要实现的方法的集合)函数compareTo定义元素的顺序。

来自Comparable 规范:

int compareTo(T o)

将此对象与指定的对象进行比较以获得顺序。 返回负整数,零或正整数,因为此对象小于,等于或大于指定对象。

如果我正在比较耳朵大小,并且假设我希望大耳朵在我的列表中排在第一位,那么我可以(重新)将compareTo定义为:

 public int compareTo(Employee e) { if (this.earSize > e.earSize) //big ears come first return -1; if (this.earSize == e.earSize) //equality return 0; else return 1; // if e.earSize > this.earSize then return 1 } 

要回答Steve Kuo的问题,我们将关键字this放在比较器中,因为当我们调用compareTo方法时

 x.compareTo(y); 

关键字this将引用x

您可以将compareTo视为对象x的方法,因此当您调用x.compareTo(y)时,您实际上是在对象x的范围内说this.compareTo(y)。

我们还可以看一个String示例:

这意味着,如果我想让“梅德韦杰夫”来到“普京”之前(因为“M”在英文字母“P”之前出现),我必须说明我希望compareTo在将梅德韦杰夫与普京比较时返回-1。

 String TheMString = "Medvedev"; String ThePString = "Putin"; 

那条线

 TheMString.compareTo(ThePString); 

将评估为-1。

现在,诸如Collections.sort( list ,comparator)之类的标准例程将能够使用compareTo返回的这些值来计算列表的[绝对]顺序。 您可能知道,排序是基于比较的操作,我们需要知道什么值是“小于”或“大于”另一个值才能进行有意义的排序。

一个重要的警告是,如果你在字符串上调用compareTo,它默认为字母顺序,所以你可以简单地告诉compareTo返回A.compareto(B),它将确保字符串有序。

通常(好吧,我应该说,在其他情况下)重新定义compareTo方法时,必须显式声明neg / zero / pos返回值。

我希望有所帮助。