如何在不同的类中更改枚举变量的值?

时间:2014-03-22 17:34:33

标签: java sorting enums

我目前正在开展一个项目,要求我对一系列歌曲进行排序。 我正在使用此问题中提供的解决方案来完成此操作,同时稍微修改它:Sorting a collection of objects

import java.util.Comparator;

public class SongComparator implements Comparator<Song> {
    public enum Order {
        YEAR_SORT, RANK_SORT, ARTIST_SORT, TITLE_SORT
    }

    public Order sortingBy;

    @Override
    public int compare(Song song1, Song song2) {
        switch (sortingBy) {
        case YEAR_SORT:
            return Integer.compare(song1.year, song2.year);
        case RANK_SORT:
            return Integer.compare(song1.rank, song2.rank);
        case ARTIST_SORT:
            return song1.artist.compareTo(song2.artist);
        case TITLE_SORT:
            return song1.title.compareTo(song2.title);
        }
        throw new RuntimeException(
                "Practically unreachable code, can't be thrown");
    }

    public void setSortingBy(Order sortBy) {
            this.sortingBy = sortingBy;
    } 
}

示例排序方法:

public void sortTitle() {
    SongComparator comparator = new SongComparator();
    SongComparator.Order sortingBy = SongComparator.Order.TITLE_SORT;

      Collections.sort(songs2, comparator);
    }

我希望能够在运行每个相应的sortingBy方法时更改sortField变量,这样它就会运行正确的比较方法。但是,我在方法中定义它的方式只是创建一个新的sortingBy变量而不更改SongComparator类中的变量。

1 个答案:

答案 0 :(得分:0)

您尚未设置比较器的sortingBy字段:

comparator.setSortingBy(sortingBy);
Collections.sort(songs2, comparator);

您最好将此值作为构造函数参数传递,以确保比较器始终处于有效状态,并且您不会重现该错误:

SongComparator comparator = new SongComparator(SongComparator.Order.TITLE_SORT);
Collections.sort(songs2, comparator);

顺便说一下,sortingBy字段不应该是公开的,并且sortingBy字段不应该是set。

为了让课程更容易使用,我会创建工厂方法:

public static SongComparator byTitle() {
    return new SongComparator(SongComparator.Order.TITLE_SORT);
}

public static SongComparator byYear() {
    return new SongComparator(SongComparator.Order.YEAR_SORT);
}
...

这样调用者中的代码就变成了:

Collections.sort(songs2, SongComparator.byTitle());

请注意,使用Java 8时,此比较器类变得不必要。你可以简单地使用

Collections.sort(songs2, Comparator.comparing(Song::getTitle));