2010-10-14 13 views
4

基本上,我有一個名爲「Employees」的Container類,裏面有一個ArrayList。這個ArrayList包含「Employee」對象,該對象又包含「EmployeeData」對象,而該對象又包含String對象,如「first」或「last」(這是員工姓名)。在Java中,如何快速排列排序字段爲多層的對象的ArrayList?

這裏的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中進行快速排序,以便在它的「僱員」的對象是按字母順序基於字符串對象「持續」?看起來有點複雜!


這是我班的一個基本設計:

class Employees{ 
    //data: 
     private ArrayList<Employee> emps = new ArrayList<Employee>(); 

    //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進行排序。

回答

3

最好的做法是將排序邏輯封裝在存儲在ArrayList Employee中的類中。通過創建compareTo(Employee)方法來實現Comparable。

import java.util.*; 

public class Employee implements Comparable<Employee> { 
    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 
+0

謝謝傑森!多好的答案。這應該讓我開始。 出於好奇,Collections.sort()實現了一個快速排序嗎? – trusktr 2010-10-14 18:32:10

+0

不,它是實現「修改mergesort」 - > http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#sort%28java.util.List%29 – 2012-05-24 20:05:45

4

Define Employee implements Comparable<Employee>

compareTo方法中,深入圖層並比較所需的字符串。然後您可以使用Collections.sort(),或者您可以將數據存儲在自然排序的SortedSet中。

+0

我不確定我該怎麼做。你可以看看我的(更新)的問題,以瞭解我的課程,我想做什麼? – trusktr 2010-10-14 17:59:07

+0

好的,首先 - 你知道Java嗎? – 2010-10-14 18:14:04

+0

我只是在學習,已經做了4周。賈森給出了很好的答案。 – trusktr 2010-10-14 18:33:17

11

你可以做一個比較,這樣的:

public class MyComparator implements Comparator<Employee> 
{ 
    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<Employee> 
{ 
    ... 
    public int compareTo(Employee e) 
    { 
    return this.getData().getLast().compareTo(e.getData().getLast()); 
    } 
    ... 
} 
+0

我不確定你的意思。我從來沒有這樣做過。我已經更新了我的問題,包括我的課程的基本佈局。你能看看我想要做什麼嗎? – trusktr 2010-10-14 17:58:13

+0

嘿,感謝您的信息,但我不知道如何實施它。 – trusktr 2010-10-14 19:20:00

2

彼得迪威斯和別人給予你很好的答案。您可以使用

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

使用您定義的比較器對myList進行排序。 < ===這是什麼意思?

在Java中,如果有些東西實現Comparable (java.lang.comparable)那麼您可以爲您的元素定義一個訂單。看起來你知道Java Generics是什麼,因爲你用它們來聲明你的ArrayList是< Employee>。這很棒,因爲您可以將一個Employee對象存儲到ArrayList中的每個條目中。到現在爲止還挺好?

但是,如果要對對象進行排序,首先必須定義一個訂單。由於對象可以有各種屬性,也許我想按照耳朵大小對我的員工進行分類。在這種情況下,我只是告訴Java我的類實現了Comparable。有了泛型,我必須指定它實現Comparable < Employee>,因爲我正在爲我的Employee對象(peons,minions,無論)定義一個訂單。

彼得迪威斯提到:

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定義了我的元素的順序。

從可比< T>規格:

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 
} 

要回答史蒂夫郭的問題,我們把關鍵字在我們的比較,因爲當我們調用compareTo方法

x.compareTo(y); 

關鍵字將參考x

你可以認爲的compareTo的作爲對象X的方法,所以,當你調用,則x.compareTo(Y)你真的從對象X的範圍內說this.compareTo(Y)。

我們也可以看看一個字符串例如:

這意味着,如果我想「梅德韋傑夫」以「普京」來之前(爲「M」的英文字母「P」之前來)我將有說明我想比較梅德韋傑夫和普京時比較返回-1。

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

後再行

TheMString.compareTo(ThePString); 

將評估爲-1。

現在如Collections.sort(列表,比較器)的標準程序將能夠使用這些值即返回的compareTo找出列表的[絕對]順序。您可能知道,排序是基於比較的操作,我們需要知道什麼值是「小於」或「大於」另一個值才能進行有意義的排序。

一個大問題是,如果你在字符串上調用compareTo,它默認爲字母順序,所以你可以簡單地告訴compareTo返回A.compareto(B),它會確保字符串的順序。

在重新定義compareTo方法時,通常(應該說,在其他情況下),您必須明確指出neg/zero/pos返回值。

我希望有幫助。

+0

哇,謝謝你解釋sova!這非常好。我現在瞭解得更多了。 – trusktr 2010-10-14 19:28:42

+1

我的朋友沒問題! Java是我的激情之一,我很樂意與您分享! – sova 2010-10-14 19:40:21