П
По-явански
@javanese_online836 подп.
8.2Kпросмотров
14 октября 2024 г.
Score: 9.0K
Разделение на Iterable и Sequence несостоятельно Как работает этот код? expr .filter { ... } .map { ... } .sorted() .take(k) .toMutableList() Зависит от того, expr: Iterable или Sequence. Если Iterable: • filter – создать копию, выкинув не соответствующее предикату, • map — создать копию, применив трансформацию, • sorted — создать копию, отсортировать, • take — создать копию, ограниченную по размеру, • toMutableList — создать копию. Если Sequence: • filter — отфильтровать итератор, • map — мапнуть итератор, • sorted — собрать итератор в коллекцию и отсортировать, • take — отдать итератор ограниченного размера, • toMutableList — собрать итератор в коллекцию. Здесь не будет нытья о том, что обе цепочки неэффективны. Миша пытается мириться с тем, что Котлин — не Раст. Здесь будет нытьё о том, что имена некоторых методов нам врут. То, что называется Iterable.filter(): List, должно называться collectMatching. Честный filter можно сделать на итераторе. Sequence.map оборачивает апстримовый итератор. List.map по этой же логике должен возвращать view на другой List. То, что сейчас называется Iterable.map, должно называться collectMapping. Сортировка — это всегда буферизация, поэтому пусть будет .collectSorted(): List. Отдельная версия для сиквенсов не имеет смысла — мы всегда собираем итератор в лист. (Зато существует отдельная версия для in-place-сортировки: MutableList.sort(): Unit. Ой, оказывается, можно обработать особый случай, а не врать, пытаясь подогнать всё под единый интерфейс!) Копирующий List.take — collectFirst. Мгновенный List.take, работающий через subList — takeLeaking. toMutableList() — collectToMutableList(). Тогда вариант с expr: Iterable выглядел бы так: expr .collectMatching { ... } .collectMapping { ... } .collectSorted() .collectFirst(k) .collectToMutableList() Теперь явно видно, что здесь происходит: копирование, копирование и ещё три раза копирование! Разделение на Iterable и Sequence тогда теряет всякий смысл: по названию операции видно, оборачивание это или копирование. К слову, list1 + list2 — тоже копирование, и выглядеть оно должно как (list1 + list2).collectToList(). Вспоминается ещё одно уродство, которое мимикрирует под коллекции: операции на строках — "qwe".map(Character::toUpperCase), "qwe".count(Character::isLetter) и тому подобные. Это недоразумение показывает нам деталь реализации — UTF-16 — выраженную через тип Character, который бесполезен и вообще не должен существовать. Если предыдущие рассуждения об операциях на коллекциях можно списать на стиль и безразличие котлина к производительности, то здесь уже вопрос корректности. Character и CharSequence — это баг.
8.2K
просмотров
2695
символов
Нет
эмодзи
Нет
медиа

Другие посты @javanese_online

Все посты канала →