Java多级比较器

Java多级比较器,java,arrays,sorting,object,comparator,Java,Arrays,Sorting,Object,Comparator,我正在解决一个问题,我必须从输入文件中提取这些“歌曲艺术家对”,并按字母顺序排序。排序的指导原则如下所示: 应该首先按作者的姓名对歌曲艺术家对进行排序 一旦按艺术家排序,如果同一艺术家有多首歌曲,它们也应该按字母顺序排序 如果艺术家名称以“the”开头,请忽略它以进行排序 我的问题是,当我对这些歌曲进行排序时,我能够正确地对艺术家进行排序,但是我不能在他们有相同艺术家的情况下对歌曲进行排序 这是输入文件的外观: Hello - Adele Yesterday - The Be

我正在解决一个问题,我必须从输入文件中提取这些“歌曲艺术家对”,并按字母顺序排序。排序的指导原则如下所示:

  • 应该首先按作者的姓名对歌曲艺术家对进行排序
  • 一旦按艺术家排序,如果同一艺术家有多首歌曲,它们也应该按字母顺序排序
  • 如果艺术家名称以“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());
        }
    }
这是正确排序后的输出结果:

    Hello - Adele
    Hey Jude - The Beatles
    Yesterday - The Beatles
    Love Me Like You Do - Ellie Goulding
    Istanbul - They Might Be Giants
我最初的想法是在数组中循环,找到同一个艺术家的歌曲,然后找到一种方法对它们进行排序,然后将它们重新插入到数组中,这有点复杂。有人告诉我,我可以使用更全面的比较器,让他们对艺术家和歌曲名称进行排序,我只需要对所有歌曲对象调用array.sort一次

有人能告诉我如何制作一个更全面的比较器,以适应这种情况吗?我目前只知道使用比较器的两种方法,即比较数值(如果a>b返回-1,如果a==b,返回0,如果a 多谢各位


PS:是我提到的java程序的一个粘贴库,如果你想对我试图解决的问题有更多的了解的话。是我正在解析的文本文件的样子,其中第一行是测试用例的数量,后面是一个数字以及歌曲艺术家对的数量。

假设您说您成功创建的类名为
SongArtistPair
,它有一个名为
effectiveAuthor()的方法
返回作者姓名,但不带
getSongName()
方法返回歌曲名称。您可以使用Java8
Comparator
API提供的这种模式

Comparator<SongArtistPair> comp = Comparator.comparing(SongArtistPair::effectiveAuthor).thenComparing(SongArtistPair::getSongName);
Comparator comp=Comparator.comparing(SongArtistAir::effectiveAuthor)。然后比较(SongArtistAir::getSongName);
在那之后,只需像平常一样使用
comp


查看Comparator API文档以了解更酷的内容

假设您说您设法创建的类名为
SongArtistPair
,它有一个名为
effectiveAuthor()
的方法,该方法返回作者的姓名,而不包含
the
,还有一个方法
getSongName()
,该方法返回歌曲的名称。您可以使用Java8
Comparator
API提供的这种模式

Comparator<SongArtistPair> comp = Comparator.comparing(SongArtistPair::effectiveAuthor).thenComparing(SongArtistPair::getSongName);
Comparator comp=Comparator.comparing(SongArtistAir::effectiveAuthor)。然后比较(SongArtistAir::getSongName);
在那之后,只需像平常一样使用
comp


检查Comparator 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;
    }
}
公共静态类SongComparator实现Comparator{
公共整数比较(歌曲a、歌曲b){
int rslt a.effectiveAuthor().compareTo(b.effectiveAuthor());
如果(rslt==0)
{
//比较歌曲名称
rslt=a.getSongName().compareTo(b.getSongName());
}
返回rslt;
}
}

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

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;
    }
}
公共静态类SongComparator实现Comparator{
公共整数比较(歌曲a、歌曲b){
int rslt a.effectiveAuthor().compareTo(b.effectiveAuthor());
如果(rslt==0)
{
//比较歌曲名称
rslt=a.getSongName().compareTo(b.getSongName());
}
返回rslt;
}
}

虽然此解决方案可以正常工作,但请您解释comparator
comp
实际上是如何首先比较作者,然后比较歌曲标题的。这是我学习Java的第一年,所以我对排序和比较器不太熟悉。所以
Comparator.comparating
是一种静态方法,它采用一个名为
Function
的函数接口,允许您提取用于比较数组中元素的键,并返回一个
Comparator
实例,然后使用另一个
函数
指定第二个键,当第一个键认为两个对象相等时,通过该键进行比较。不确定这是否有意义,Javadocs应该比我解释得更好though@Wup123除了答案之外,你可以看看这篇文章。@Dummy我确实理解
函数
接口是如何工作的,但是请你详细说明一下键是如何创建的?虽然这个解决方案可以正常工作,请您解释一下comparator
comp
实际上是如何先比较作者,然后比较歌曲标题的。这是我学习Java的第一年,所以我对排序和比较器不太熟悉。所以
Comparator.comparating
是一种静态方法,它采用一个名为
Function
的函数接口,允许您提取用于比较数组中元素的键,并返回一个
Comparator
实例,然后使用另一个
函数
指定第二个键,当第一个键认为两个对象相等时,通过该键进行比较。不确定这是否有意义,Javadocs应该比我解释得更好though@Wup123除了答案之外,你可以看看这篇文章。@Dummy我确实理解
的功能