2012-11-21 22 views
3

我有一系列需要使用規則訂購的對象。但是我需要能夠切換規則,但我有一套有限的訂購規則。哪個數據結構會是最好的選擇?使用四條規則之一訂購清單的最佳實踐

例如,我有這個類:

class Test { 
    public final int amount; 
    public final int cost; 
    public final String name; 
    public final int whatever; 
    // ... 

    // TODO: add a constructor to set the fields :-) 
} 

我如何可以存儲這些領域通過量,成本,名稱或任何命令他們。但只是其中的一個規則。

我可以想象使用ArrayListHashSet,我稱之爲排序功能與自定義Comparator。但我無法想象這是效率。我認爲這對移動設備很重要。什麼是更好的方式來實現這一目標?

回答

5

您無法使用Set進行排序,因爲它沒有任何順序。如何擁有List和定製Comparator<T>的概念是合理的。

您應該使用該解決方案,並不在意此時的性能。如果您對獲得的結果感到不滿意,請嘗試提出更好的解決方案。

最好的解決方案是以正確的順序從存儲中讀取數據。我不知道你的應用如何存儲這種結構。因此,我無法幫助你。但是實施類似的解決方案,你會發現這並不是那麼糟糕。

在移動設備上重要的是內存使用情況。如果您的應用程序將使用這些排序操作的很多,你可以創建比較器,枚舉所以他們將被載入只有一次,除了可以簡化代碼

private enum TestComparator implements Comparator<Test> { 
BY_NAME { 

    @Override 
    public int compare(Test o1, Test o2) { 

     //We validate first against null 

     return o1n.name.compareTo(o2.name); 

    }    
    } 
BY_WHATEVER{ 

    @Override 
    public int compare(Test o1, Test o2) { 

     //We validate first against null 
     return (o1.whatever<o2.whatever ? -1 : (o1.whatever==o2.whatever ? 0 : 1)); 
    }    
    } 

} 
3

這樣做:

class Test { 
public final int amount; 
public final int cost; 
public final String name; 
public final int whatever; 
// ... 

// TODO: add a constructor to set the fields :-) 

    class TestAmountComparator implements Comparator<Test> { 
     @Override 
     public int compare(Test t1, Test t2) { 
      return Integer.valueOf(t1.amount).compareTo(Integer.valueOf(t2.amount))   
     } 
    } 

    class TestCostComparator implements Comparator<Test> { 
     @Override 
     public int compare(Test t1, Test t2) { 
      return Integer.valueOf(t1.cost).compareTo(Integer.valueOf(t2.cost))   
     } 
    } 

}

存儲您的測試對象ArrayList(或任何其他集合),然後對它們進行排序是這樣的:

List<Test> list = new ArrayList<Test>(myTest); //your Test list 
//sorting 
Collections.sort(list, new TestAmountComparator()); //sort by amount 
Collections.sort(list, new TestCostComparator()); //sort by cost 
+2

將「cost」作爲Integer.compare(t1.cost,t2.cost)進行比較效率更高。 「金額」相同 –

1

我寧願實施類比界面和執行compareTo類的方法。它提供了跨不同數據結構進行排序的一致性行爲。 在這種情況下,比較器接口將僅在需要特殊分類時使用。

class Test implements Comparable { 
    public final int amount; 
    public final int cost; 
    public final String name; 
    public final int whatever; 
    // ... 
    //add equals ,hashcode, and compareTo method in the class... 
    // TODO: add a constructor to set the fields :-) 
} 

如果實例是唯一且可比較的,則可以使用TreeSet。否則,否則您必須使用列表並使用Collection.sort函數對它們進行排序。

您可以根據訪問使用情況決定DS。如果您要訪問的順序使用LinkedList的其他用戶的ArrayList元素

+0

TreeSet提示正常。但不是這個問題,因爲OP要求在同一個模型上使用不同的比較器。 –

+0

其實TreeSet的排序由如量能有實例與等量如果返回的compareTo 1時t1.amount == t2.amount –

+0

有java.util.PriorityQueue中,它也進行排序,但可以容納複本 –

1

我的版本:

class Test3 implements Comparable<Test3> { 
    public int amount; 
    //... 

    Comparator<Test3> comparator; 

    public void setComparator(Comparator<Test3> comparator) { 
     this.comparator = comparator; 
    } 

    @Override 
    public int compareTo(Test3 o) { 
     return comparator.compare(this, o); 
    } 
} 
0

這是我們如何使用TreeSet中不失重複:

import java.util.Comparator; 
import java.util.TreeSet; 

    public class Test { 
     int amount; 

     Test(int amount) { 
      this.amount = amount; 
     } 

     public static void main(String args[]) throws Exception { 
      Comparator<Test> c = new Comparator<Test>() { 
       @Override 
       public int compare(Test o1, Test o2) { 
        if (o1.amount >= o2.amount) { 
         return 1; 
        } 
        return -1; 
       } 
      }; 
      TreeSet<Test> s = new TreeSet<Test>(c); 
      s.add(new Test(2)); 
      s.add(new Test(1)); 
      s.add(new Test(1)); 
      for (Test t : s) { 
       System.out.println(t.amount); 
      } 

     } 
    } 

此打印:

1 
1 
2 
+0

你比較做也不返回有效的結果,如果量是相等的。 –

+0

但是,這就是爲什麼相等的對象停留在TreeSet中,整個事情正常工作。 –