在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声明为
但是,如果要对对象进行排序,首先必须定义顺序。 由于对象可以具有各种属性,因此我可能希望按照耳朵大小对员工进行排序。 在这种情况下,我只是告诉Java我的类实现了Comparable。 使用generics,我必须指定它实现Comparable
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返回值。
我希望有所帮助。