2016-01-21 4 views
1

У меня есть два решения с мыслью о том, что перечисление формирует библиотеку компараторов:методы перечисления переопределить с помощью лямбда-выражения

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

} 

Если я хочу, чтобы заменить значение перечисления, где ожидается Компаратор, в первом решении я должен сказать SongComparator.BY_TITLE.get(); тогда как во втором решении я могу просто сказать SongComparator2.BY_TITLE.

Второй в этом смысле лучше, однако мне не нравится писать общедоступный int compare ... и т. Д. Для каждого значения перечисления и хотел вместо этого использовать Comparator.comparing, как в первом подходе. Есть ли способ достичь этого?

Я почти хотел сказать что-то вроде: BY_TITLE {return Comparator.comparing (Song :: getTitle); };

+2

http://stackoverflow.com/q/23361418/2711488 Обратите внимание, что пример в этом вопросе показывает, как избежать вызова 'получить()' в делегации вариант. – Holger

+0

Вам действительно нужно перечисление? Почему бы не сделать эти 3 константы компаратора класса, а не экземпляры enum? –

ответ

5

Что случилось с:

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

} 
+0

Ах да, это будет трюк! Просто дважды проверьте - если эта реализация должна была быть передана методу sort (...), например. Я прошел SongComparator.BY_TITLE. Я предполагаю, что функция выделения ключей (Comparator.comparing) будет вызываться только один раз, чтобы инициализировать поле enum, а не во время каждого обратного вызова, который сортировка сделает для метода переопределенного сравнения? Вместо этого, я полагаю, все, что происходит, - это один шаг делегирования из метода переопределенного сравнения enum, который используется составленным компаратором? – Tranquility

+1

Enums - просто причудливые способы объявления классов. Когда все конструкторы экземпляров будут запущены, вы просто останетесь с экземпляром перечисления, который является обычным объектом. –

Смежные вопросы