Java多级比较器

时间:2017-04-04 04:24:37

标签: java arrays sorting object comparator

我正在研究一个问题,我必须把这些"歌曲 - 艺术家对"从输入文件和按字母顺序排序。排序指南如下:

  • 首先应按照作者的名字对歌曲 - 艺术家对进行排序。
  • 一旦艺术家排序,如果同一位艺术家有多首歌曲,他们也应按字母顺序排序。
  • 如果艺术家姓名以""开头,请忽略它以进行排序。

我的问题是,当我对这些进行排序时,我能够正确地对艺术家进行排序,但是我不能在他们拥有相同艺术家的条件下对歌曲进行排序。

这是输入文件的样子:

    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()方法返回作者的字符串,而不是&#34;名称前面的&#34;)

使用Song对象和比较器数组调用Arrays.sort()时,这是我得到的输出:

    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

我最初的想法是遍历数组并找到具有相同艺术家的歌曲,并找到一种方法对它们进行排序并将它们重新插入到该数组中,这有点复杂。有人告诉我,我可以使用更全面的比较器,让它们对艺术家和歌曲名称进行排序,并且我只需要为所有Song对象调用一次Arrays.sort。

有人可以告诉我如何制作一个与这种情况相关的更全面的比较器吗?我目前只知道两种方法,我可以使用比较器,比较数值(如果a> b返回-1,如果a == b,返回0,如果a&lt; b,返回1),和字符串值(又名a.compareTo(b)),但我不知道我怎么能够制作一个更精细的比较器来帮助我能够先按艺术家排序然后再按歌曲名称排序。

谢谢

PS:This是我提到的java程序的pastebin,如果你想更深入地了解我想解决的问题。 This是我正在解析的文本文件的样子,其中第一行是测试用例的数量,后跟一个带有歌曲 - 艺术家对数量的数字。

2 个答案:

答案 0 :(得分:6)

让我们说你设法创建的课程称为SongArtistPair,并且它有一个名为effectiveAuthor()的方法,它返回作者的名字而没有{{1} },以及返回歌曲名称的方法The。您可以使用Java 8 getSongName() API提供的此模式。

Comparator

之后,只需使用Comparator<SongArtistPair> comp = Comparator.comparing(SongArtistPair::effectiveAuthor).thenComparing(SongArtistPair::getSongName); 正常

检查Comparator API文档以获取更多精彩内容HERE

答案 1 :(得分:2)

在比较方法中,如果艺术家名称相同,则比较歌曲标题。像这样:

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;
    }
}