Эффективно найти headSet из SortedSet в Java
В SortedSet
конкретно TreeSet
В Java 8 и более поздних версиях существует ли более эффективный способ определения подходящего подмножества первых элементов (" headSet ") элементов?
сценарий
Представить Person
объекты с birthDate
член. Мы хотим исключить несовершеннолетних и оставить в нашем SortedSet только взрослых.
Или, говоря более технически... У меня есть коллекция объектов, чей естественный порядок compareTo
метод Comparable
) основывается на значении даты и времени ( Joda-Time) DateTime
объект, или это может быть java.time ZonedDateTime
). Я хочу удалить более старые элементы, которые имеют " устаревшее " значение, что означает, что их значение даты и времени теперь меньше, чем желаемое значение даты и времени.
Уже отсортировано
Я хочу воспользоваться тем, что элементы уже отсортированы. Таким образом, используя предикат с removeIf
в потоке будет неэффективным, так как он сравнивает все элементы в SortedSet. Учитывая отсортированный порядок, нет необходимости продолжать сравнение после обнаружения первого несоответствия.
Roll-Your-Own
Я полагаю, что мог бы сам написать код для поиска и удаления, но это похоже на то, что будет встроено в платформу Collections.
DateTime minimumBirthDateTime = DateTime.now().minusYears( 18 );
SortedSet<Person> persons = … ;
while ( persons.pollFirst() != null ) {
Person p = persons.first();
if( p.getBirthDate().isBefore( minimumBirthDateTime ) ) {
persons.remove( p ); // Remove minors from our SortedSet, leaving only adults.
}
}
Временное решение
Один обходной путь: фиктивный объект.
Построить подделку Person
объект с минимальной датой-временем рождения, который мы хотим для сравнения. Тогда мы можем использовать изящные методы NavigableSet
интерфейс реализован TreeSet
,
Другой обходной путь: поддельный подкласс, для фиктивного объекта.
Предположим, Person
класс слишком сложен в своей конструкции, чтобы сделать фиктивный экземпляр. Создать подкласс Person
назвал что-то вроде Person_FakeForSortedSetComparing
, Дайте этому подклассу конструктор только для этой специальной цели. В этом примере передается объект DateTime для минимальной даты рождения.
Person_FakeForSortedSetComparing youngestPossibleAdult = new Person_FakeForSortedSetComparing( minimumBirthDateTime );
SortedSet<Person> minors = persons.headSet( youngestPossibleAdult );
persons.removeAll( minors );