2012-05-22 41 views
3

排序列表我編碼是這樣的:返回在Java中

List<Bean> beans = service.findBeans(); 
Collections.sort(beans, new BeanComparator()); 
return beans; 

它完美。我所尋找的是一個捷徑只有一條線要做到這一點:

return somelibrary.Collections.sort(service.findBeans(), new BeanComparator()); 

或者:

return somelibrary.newList(service.findBeans(), new BeanComparator()); 

注意,它需要一個可變的列表。

+7

原始有什麼問題? –

+1

圖書館的目的是什麼,如果它只是做'Collections.sort'已經提供的完全相同的東西? – mellamokb

+0

沒有錯。有用。我正在尋找一種快捷方式,只用一行就能完成我想要的功能。 – falsarella

回答

9

這是一條線:

List<Bean> beans = service.findBeans(); Collections.sort(beans, new BeanComparator()); return beans; 

但更嚴重的是,Java是不是真的單行正確的語言。另外,僅僅因爲某件事情是單行事件並不意味着它會更好。例如,我最初是驚訝地發現,這樣的:

return condition ? a : b; 

創建比

if(condition) 
    return a; 
else 
    return b; 

更長的字節碼但是,這是語言和編譯器只是如何。

如果您堅持一個內膽,GuavaOrdering可以做到這一點:

return Ordering.from(new BeanComparator()).sortedCopy(service.findBeans()); 

返回的列表是修改的,序列化,並進行隨機訪問。

效率明智我認爲在開銷方面有點浪費。而且你現在依賴於第三方庫。你基本上使用非常強大的工具來完成一項非常簡單的任務。如果這就是你所使用的全部內容,那就太過分了。

+0

您使用的線越多,閱讀代碼越容易! – jahroy

+1

@jahroy並不總是如此。有混亂的代碼這樣的事情。 – trutheality

+1

@thereality有這樣的事情,Perl;我不認爲第一個版本特別混亂。一個'sort'版本就地排序,但返回一個對輸入參數的引用將被設計得非常糟糕,因爲大多數人會希望從這樣的API返回一個已排序的副本,並且輸入參數保持不變。 Python--一種通常在短文和可讀文件之間保持良好平衡的語言(比Java更重要) - 對於給定的問題,看起來幾乎完全相同。 – Voo

4

我相信下面的函數將產生你想要的結果。只要把它放在你選擇的課堂上。

public static <T> List<T> sort(List<T> list, Comparator<? super T> compare) { 
    Collections.sort(list, compare); 
    return list; 
} 
1

我想,如果你沒有重複,不介意哈克代碼,你可以使用:

return new ArrayList<Bean>(new TreeSet<Bean>(service.findBeans())); 
+0

不幸的是,這種方法使用自然排序來排序,而不允許我們使用自定義比較器。 – falsarella

1

我覺得貼了原來的問題是有效的。因爲「Collections.sort(..)」方法排序傳入的集合,如果你想保持你原來的集合,你需要做以下的預期副作用:

List<Bean> beans = service.findBeans(); 
List<Bean> sortedBeans = new ArrayList<Bean>(beans); 
Collections.sort(sortedBeans, new BeanComparator()); 
return sortedBeans; 

在上面的例子中,我們對服務方法返回的Collection進行排序可能不是那麼重要。但是,如果我們正在排序的Collection是一個方法參數,並且調用者不希望Collection傳入排序?

我通常更喜歡有沒有後果的方法。

由於 「Collections.sort(..)」 影響的名單,我已經寫了下面的代碼:

public void doSomethingWithBeansInOrder(List<Bean> beans) { 
    Collection<Bean> sortedBeans = new ArrayList<Bean>(beans); 
    Collections.sort(sortedBeans, ...comparator...; 

    for (Bean bean : sortedBeans) { 
     .. do something 
    } 
} 

我覺得 「sortedBeans」 的定義難看。

如果「(Collections.sort(..)」(或類似的東西),返回一個新的集合,並沒有影響傳入的集合,我可以這樣寫:

public void doSomethingWithBeansInOrder(List<Bean> beans) { 
    for (Bean bean : Collections.sort(beans, ...comparator...) { 
     .. do something 
    } 
} 

的答案GuavaOrdering是最好的,在我看來。

2

你可以使用Apache CollectionUtils一個比較器和一個空的列表整理列表。

CollectionUtils.collate(service.findBeans().iterator(),Collections.EMPTY_LIST.iterator(),new beanComparator()) 

有限公司llectionUtils真的應該添加一個實用的方法,返回排序列表...

經典反駁使用多行是LOGGING。爲了可讀性目的,日誌記錄不應占用多行。當您試圖找出代碼實際在做什麼時,記錄就是靜態噪音,但記錄相當關鍵。

所以登錄要緊湊(在一行中),安靜(不應該拋出異常/是nullsafe),應該是高性能(如果關閉應該不會引入超越isDebugOn多餘的處理()檢查。

二反駁。能說流利的接口,如JOOQ正變得更加普遍

1

首先,Java的8引入了List接口上sort()梅託德所以,分揀實際列表的一個例子是:

List<Integer> integerList = Arrays.asList(3, 2, 1); 
integerList.sort(Comparator.naturalOrder()); 
return integerList; 

在這裏,我使用了預定義的naturalOrder()比較器,該比較器依次依賴於Comparable,但也可以使用自定義比較器。這仍然需要兩個陳述。

但是,如果期望的行爲是創建一個新的排序列表,並留下orignial因爲它以前,我想流將做到這一點最簡單的方法:

integerList.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList()); 

同樣的事情如上所述適用於比較器。