【问题标题】:enum override methods using lambda expressions使用 lambda 表达式的枚举覆盖方法
【发布时间】:2016-01-21 15:53:14
【问题描述】:

我有两个解决方案来让枚举形成一个比较器库:

public enum SongComparator {

    BY_TITLE(Comparator.comparing(Song::getTitle)),
    BY_ARTIST(Comparator.comparing(Song::getArtist)),
    BY_DURATION(Comparator.comparing(Song::getDuration));

    private Comparator<Song> comp;

    private SongComparator(Comparator<Song> comp) {
        this.comp = comp;
    }

    public Comparator<Song> get() {
        return comp;
    }
}

还有……

public enum SongComparator2 implements Comparator<Song> {

    BY_TITLE {
        public int compare(Song s1, Song s2) {
            return s1.getTitle().compareTo(s2.getTitle());
        };
    },
    BY_ARTIST {
        public int compare(Song s1, Song s2) {
            return s1.getArtist().compareTo(s2.getArtist());
        };
    },
    BY_DURATION {
        public int compare(Song s1, Song s2) {
            return Integer.compare(s1.getDuration(), s2.getDuration());
        };
    };

}

如果我想在需要 Comparator 的地方替换一个枚举值,在第一个解决方案中我必须说 SongComparator.BY_TITLE.get();而在第二个解决方案中,我只能说 SongComparator2.BY_TITLE。

从这个意义上说,第二种方法更好,但是,我不喜欢为每个枚举值编写 public int compare... 等,而是希望像第一种方法一样使用 Comparator.comparing。有没有办法做到这一点?

我几乎想说:BY_TITLE { return Comparator.comparing(Song::getTitle); };

【问题讨论】:

  • stackoverflow.com/q/23361418/2711488 请注意,该问题中的示例向您展示了如何避免在委托变体中调用 get()
  • 你真的需要枚举吗?为什么不将这 3 个比较器设为类的常量,而不是枚举实例?

标签: lambda interface enums java-8 comparator


【解决方案1】:

有什么问题:

public enum SongComparator implements Comparator<Song> {

    BY_TITLE(Comparator.comparing(Song::getTitle)),
    BY_ARTIST(Comparator.comparing(Song::getArtist)),
    BY_DURATION(Comparator.comparing(Song::getDuration));

    private Comparator<Song> comp;

    private SongComparator(Comparator<Song> comp) {
        this.comp = comp;
    }

    public int compare(Song s1, Song s2) {
        return comp.compare(s1, s2);
    };

}

【讨论】:

  • 啊,是的,这样就行了!只是为了仔细检查 - 如果这个实现被传递给一个 sort(...) 方法,例如我通过了 SongComparator.BY_TITLE。我假设密钥提取器函数(Comparator.comparing)只会被调用一次,以初始化枚举的字段,而不是在排序将对覆盖的比较方法进行的每个回调期间?相反,我假设所有发生的事情都是从枚举的覆盖比较方法到组合比较器持有的委托的一个步骤?
  • 枚举只是声明类的奇特方式。运行所有实例构造函数后,您只剩下一个枚举实例,它是一个普通对象。
猜你喜欢
  • 2016-09-23
  • 1970-01-01
  • 2021-07-18
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多