Collections DSL
From IT SPb Academy
Contents[hide] |
Тип sequence<T>
Тип sequence<T> это аналог Iterable<T> (java) или IEnumerable <T> (c#), но в отличае от них, это не interface и у него нельзя напрямую вызвать метод iterator() или GetEnumerator().
Типу sequence<T> не соответствует никакой класс, но к нему можно приводить любой тип приводимый к Iterable<T>.
Создать экземпляр sequence-а можно с помощью специальной конструкции
new sequence [ ... ]
где в квадратных скобках пишется код итерации. В блоке итерации можно испрользовать специальные statements:
- yield <expression>; возвращает значение на очередном шаге итерации - stop; останавливает итерацию (нормально итерация останавливается просто когда поток управления покидает блок итерации)
Например, бесконечную последовательность натуральных чисел можно создать так:
Другой способ создать sequence это просто создать любой java.lang.Iterable и привести его к типу sequence:
Поскольку sequence<T> это не класс, то нельзя создать класс “имплементирующий” sequence. Вместо этого, класс в котором можно что-то итерироавть должен создавать sequence и возвращать ее из какого-нибудь метода.
Вот, например, как выглядит класс FibonacciSequence:
Тип list<T>
Типу list<T> также не соответствует никакой класс, но его можно приводить к типу интерфейса java.util.List и обратно. Тип list<T> приводится к типу sequence<T>. Тип list<T> можно получить из sequence<T> применением операции toList.
Цикл foreach
Итерирует sequence:
Операции над sequence<T>
Большенство операций над sequence принимает в качестве аргумента блок кода того или иного типа, в котором иплементируется соответствующая функция (обычно) от элемента входной sequence.
Все блоки кода обладают свойствами closure. Т.е. в них можно использовать (R/W) элементы контекста в месте написания блока кода – локальные переменные, параметры методов и выражение this.
Существует несколько исключений:
- нельзя обращаться к переменным циклов; - нельзя использовать ключевое слово super; - у this можно использовать только public members (к счастью, они все public)
Например, в FibonacciSequence (выше) в теле итератора используется переменная max.
toList operation
Создает list<T> по входной sequence<T> .
map operation
Создает произвольную sequence<M> по входной sequence<T>.
Внутри map-блока можно использовать специальные statements:
- yield <expression>; возвращает значение на очередном шаге итерации. допустимо несколько или ниодного для каждого эдемента входной sequence - stop; останавливает итерацию и завершает маппирование - skip; пропускает текущий элемент входной sequence
В примере ниже на вход подается последовательность напуральных чисел. При маппировании все нечетные числа пропускаются, а для каждого четного числа конструируются возвращаются две сторки:
forEach operation
Операция ничего не возвращает, просто итерирует входную sequence.
Внутри forEach-блока можно использовать специальные statements:
- stop; останавливает итерацию. - skip; пропускает текущий элемент входной sequence
where operation
Возвращает sequence с элементами того-же типа что и во входящей sequence, где каждый элемент удовлетворяет условию.
select operation
Возвращает sequence<M> такого-же размера как входная sequence<T>.
В примере ниже на вход подается последовательность напуральных чисел. Затем остаются только четные числа, затем для каждого из них конструируюется сторка: