问题
I am working on a problem where I must take these "Song-artist pairs" from an input file and sort alphabetically. The guidelines to the sorting goes like so:
- Should sort the song-artist pairs by the name of the author first.
- Once sorted by the artists, if there are multiple songs by the same artist, they should be sort alphabetically as well.
- If the artists name starts with "The", ignore it for sorting purposes.
My problem is that when I am sorting these, I am able to get the artists sorted properly, but then I cannot sort the songs under the conditions that they have the same artist.
This is what the input file would look like:
Hello - Adele
Yesterday - The Beatles
Love Me Like You Do - Ellie Goulding
Hey Jude - The Beatles
Istanbul - They Might Be Giants
I have properly read through the input file, but so far my comparator only sorts the artists alphabetically. This is what my comparator looks like:
public static class SongComparator implements Comparator<Song>{
public int compare(Song a, Song b){
return a.effectiveAuthor().compareTo(b.effectiveAuthor());
}
}
(I have created a class to easily keep track of the songs and their artists. The effectiveAuthor() method returns the string of the author without the "The " in front of the name)
When calling Arrays.sort() with the array of Song objects and comparator, this is the output I get:
Hello - Adele
Yesterday - The Beatles
Hey Jude - The Beatles
Love Me Like You Do - Ellie Goulding
Istanbul - They Might Be Giants
This is what the output with the proper sorting would look like:
Hello - Adele
Hey Jude - The Beatles
Yesterday - The Beatles
Love Me Like You Do - Ellie Goulding
Istanbul - They Might Be Giants
My original idea was to loop through the array and find the songs with the same artist, and find a way to sort them and re-insert those back into that array, which is a bit complex. I was told that I could use a more comprehensive comparator by having them sort both the artist and song names, and that I would only need to call Arrays.sort once for all of the Song objects.
Can somebody show me how to make a more comprehensive comparator that would pertain to this situation? I currently only know two ways that I can use a comparator, which is to compare numerical values(aka if a > b return -1, if a == b, return 0, and if a < b, return 1), and String values(aka a.compareTo(b)), but I do not know how I would be able to make a more elaborate comparator to help me out with being able to sort by artist first and then the song name.
Thank you
PS: This is a pastebin to the java program I mentioned, if you would like more insight on the problem I am trying to solve. This is what the text file would look like that I am parsing through, where the first line is the number of test cases, followed by a number with the amount of song-artist pairs.
回答1:
Let's say the class you said you managed to create is called SongArtistPair
and it has a method called effectiveAuthor()
which returns the author's name without the The
, and a method getSongName()
which returns the name of the song. You can use this pattern offered by the Java 8 Comparator
API.
Comparator<SongArtistPair> comp = Comparator.comparing(SongArtistPair::effectiveAuthor).thenComparing(SongArtistPair::getSongName);
After that, just use that comp
as normal
Check Comparator API docs for more cool stuff HERE
回答2:
In your compare method, compare the song titles if the artists names are identical. Like this:
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;
}
}
来源:https://stackoverflow.com/questions/43198221/java-multi-level-comparator