2017-04-04 96 views
1

我正在處理一個問題,我必須從輸入文件中挑選這些「歌手 - 藝術家對」並按字母順序進行排序。排序的指導方針如下所示:Java多級比較器

  • 應該首先按照作者姓名對歌曲藝術家對進行排序。
  • 一旦由藝術家分類,如果同一個藝術家有多首歌曲,他們也應該按字母順序排序。
  • 如果藝術家名稱以「The」開頭,請忽略它以進行排序。

我的問題是,當我排序這些,我能夠讓藝術家排序正確,但我不能排序的條件下,他們有相同的藝術家的歌曲。

這是輸入文件會是什麼樣子:

Hello - Adele 
    Yesterday - The Beatles 
    Love Me Like You Do - Ellie Goulding 
    Hey Jude - The Beatles 
    Istanbul - They Might Be Giants 

我通過輸入文件已經正確讀取,但到目前爲止,我只比較字母順序排列的藝術家。這是我比較樣子:

public static class SongComparator implements Comparator<Song>{ 
     public int compare(Song a, Song b){ 
      return a.effectiveAuthor().compareTo(b.effectiveAuthor()); 
     } 
    } 

(我創建了一個類來輕鬆地跟蹤歌曲和他們的藝術家的effectiveAuthor()方法返回了筆者的字符串沒有「的」前面的。名稱)的

當宋對象和比較器的陣列調用Arrays.sort(),這是輸出I得到:

Hello - Adele 
    Yesterday - The Beatles 
    Hey Jude - The Beatles 
    Love Me Like You Do - Ellie Goulding 
    Istanbul - They Might Be Giants 

這是正確的排序輸出將是什麼樣子:

Hello - Adele 
    Hey Jude - The Beatles 
    Yesterday - The Beatles 
    Love Me Like You Do - Ellie Goulding 
    Istanbul - They Might Be Giants 

我最初的想法是循環訪問數組,並找到同一位藝術家的歌曲,並找到一種方法對它們進行排序並將它們重新插入該數組中,這有點複雜。有人告訴我,我可以使用更全面的比較器,讓他們排序藝術家和歌曲名稱,並且我只需要爲所有歌曲對象調用Arrays.sort一次。

有人可以告訴我如何做一個更全面的比較,將涉及到這種情況?我目前只知道兩種方法可以使用比較器,即比較數值(如果a> b返回-1,如果a == b,則返回0,如果返回1則返回<),以及String值(又名a.compareTo(b)),但我不知道如何能夠做出更精細的比較來幫助我排序,先按藝術家排序,然後再按歌曲名稱排序。

謝謝

PS:This是引擎收錄到我提到的,如果你想在我試圖解決這個問題更深入的Java程序。 This是文本文件看起來像我正在解析的內容,其中第一行是測試用例的數目,後面是一個包含歌曲 - 藝術家對的數字。

回答

1

comp正常

檢查比較API文檔在您的比較方法,比較歌曲標題,如果藝術家的名字是相同的。像這樣:

public static class SongComparator implements Comparator<Song>{ 
    public int compare(Song a, Song b){ 
     int rslt a.effectiveAuthor().compareTo(b.effectiveAuthor()); 
     if (rslt ==0) 
     { 
      // compare song names 
      rslt = a.getSongName().compareTo(b.getSongName()); 
     } 
     return rslt; 
    } 
} 
3

比方說,你說你成功地創建類被稱爲SongArtistPair,它有一個名爲effectiveAuthor()方法,它返回作者的名字,而不The和方法getSongName()返回歌曲的名稱。您可以使用由Java 8 Comparator API提供的這種模式。

Comparator<SongArtistPair> comp = Comparator.comparing(SongArtistPair::effectiveAuthor).thenComparing(SongArtistPair::getSongName); 

之後,只需使用更多很酷的東西HERE

+0

雖然這個解決方案能夠正常工作,但是請您解釋一下比較器'comp'如何比較作者和歌曲標題。這是我的Java第一年,所以我不完全熟悉排序和比較器。 – Wup123

+0

因此'Comparator.comparing'是一個靜態方法,它接受一個名爲'Function'的函數接口,該接口允許您提取用於比較數組中元素的**鍵**並返回一個「比較器」實例,然後使用另一個'Function'指定第二個**鍵**,以便通過第一個**鍵**認爲兩個對象相等時進行比較。不知道這是否合理,Javadocs應該比我更好地解釋它 – Dummy

+0

@ Wup123除了答案,您可能會看看這篇文章[這解釋了Lambda解決方案與非Lambda解決方案相比](http:///www.baeldung.com/java-8-sort-lambda)。 – SubOptimal