Eclipse Collections — это платформа Java Collections с открытым исходным кодом, которая позволяет писать функциональный, свободный код на Java.
история
Eclipse Collections начиналась как фреймворк коллекций под названием Caramel в Goldman Sachs в 2004 году. С тех пор фреймворк развивался, и в 2012 году он был открыт для GitHub в качестве проекта GS Collections. За эти годы около 40 или около того разработчиков из одной компании внесли свой вклад в структуру коллекций. Чтобы максимально использовать возможности проекта с открытым исходным кодом, GS Collections был перенесен в Eclipse Foundation, который в 2015 году был переименован в Eclipse Collections. Теперь эта структура полностью открыта для сообщества и принимает взносы!
Цели дизайна
Eclipse Collections была разработана для предоставления многофункционального, функционального, свободного и интересного API, а также структур данных с эффективным использованием памяти, обеспечивая при этом совместимость с коллекциями Java. Он предоставляет отсутствующие типы, такие как Bag , Multimap , Stack , BiMap , Interval .
Эволюция рамок
За последние 14 с лишним лет фреймворк стал более RichIterable обладает наивысшим интерфейсом: теперь в RichIterable содержится более 100 методов. Эти методы были включены в интерфейс после тщательного обсуждения. Ниже приведены шаги, которые мы предпринимаем при добавлении API:
1. Вариант использования: большинство методов, добавленных в платформу, мотивируются требованиями пользователя. Пользователи будут поднимать либо проблему, либо напрямую запрос на извлечение проекта, а затем мы начинаем обсуждение.
2. Static Utility vs API: Eclipse Collections имеет статические служебные классы, такие как ListIterate , ListIterate и т. Д. Эти статические служебные классы позволяют нам ListIterate прототипы наших функций перед добавлением их в качестве API. Если методы статической утилиты интенсивно используются, то в следующем выпуске мы попытаемся реализовать этот метод в виде API на интерфейсе коллекции, чтобы обеспечить богатый и свободный опыт кодирования.
Например: Iterate#groupByAndCollect() в настоящее время реализован в статической утилите. Поскольку этот метод часто используется, он оправдывает добавление его в качестве API в RichIterable чтобы обеспечить богатый, функциональный и свободный опыт кодирования. Существует открытая проблема, если вы хотите помочь нам.
3. Переопределения ковариантов. Мы логически переопределяем методы API, так что API возвращает тип, соответствующий его поведению.
Например: RichIterable имеет API-интерфейс select() который похож на filter() который возвращает все элементы коллекций, которые оценивают значение true для Predicate . Ниже описано, как API определяется на каждом интерфейсе:
|
1
2
3
4
5
6
7
8
|
// RichIterableRichIterable<T> select(Predicate<? super T> predicate);// ListIterableListIterable<T> select(Predicate<? super T> predicate);// MutableListMutableList<T> select(Predicate<? super T> predicate) |
Как вы можете видеть, select() на
— RichIterable возвращает RichIterable
— ListIterable возвращает ListIterable
MutableList возвращает MutableList
4. Перегрузка с помощью Target. Иногда возможно, что нам нужна коллекция, отличная от возвращенной. Чтобы сделать его эффективным и быстрым, мы создаем перегруженный метод, который принимает целевую коллекцию. Целевые коллекции используются для накопления результатов и возврата целевой коллекции.
Например: как описано выше, метод select() в MutableList возвращает MutableList . Тем не менее, что если вы хотите MutableSet ? Доступен перегруженный метод select() который принимает целевую коллекцию, которая может быть набором.
|
1
2
3
4
5
6
7
8
9
|
MutableList<Integer> integers = Lists.mutable.with( 1, 2, 2, 3, 3, 3, 4, 4, 4, 4);MutableList<Integer> evens = integers.select(each -> each % 2 == 0);Assert.assertEquals(Lists.mutable.with(2, 2, 4, 4, 4, 4), evens);MutableSet<Integer> uniqueEvens = integers.select( each -> each % 2 == 0, Sets.mutable.empty());Assert.assertEquals(Sets.mutable.with(2, 4), uniqueEvens); |
5. Симметрия: Eclipse Collections предлагает примитивные коллекции. Мы стараемся поддерживать симметрию между коллекциями объектов и примитивными коллекциями, чтобы обеспечить полное взаимодействие с пользователем.
Реализация API на практике
Давайте реализуем простой API RichIterable#countBy() который был добавлен в выпуске Eclipse Collections 9.0.0: Мотивация для этого API была пользователями, которые упоминали о необходимости collect() коллекцию в Bag . В Eclipse Collections collect() похож на map() а Bag — это структура данных, которая поддерживает отображение объекта на счетчик.
|
1
2
3
4
5
6
7
8
9
|
MutableList<String> strings = Lists.mutable.with( "1", "2", "2", "3", "3", "3", "4", "4", "4", "4");Bag<Integer> integers = strings.collect( Integer::valueOf, Bags.mutable.empty());Assert.assertEquals(1, integers.occurrencesOf(1));Assert.assertEquals(2, integers.occurrencesOf(2));Assert.assertEquals(3, integers.occurrencesOf(3));Assert.assertEquals(4, integers.occurrencesOf(4)); |
Приведенное выше решение для подсчета целых чисел сработало, однако оно не было интуитивно понятным. Неопытному разработчику может быть трудно реализовать это решение. Итак, мы решили добавить countBy() и теперь код выглядит более функциональным, плавным и, более того, интуитивно понятным.
|
1
2
3
4
5
6
7
|
MutableList<String> strings = Lists.mutable.with( "1", "2", "2", "3", "3", "3", "4", "4", "4", "4");Bag<Integer> integers = strings.countBy(Integer::valueOf);Assert.assertEquals(1, integers.occurrencesOf(1));Assert.assertEquals(2, integers.occurrencesOf(2));Assert.assertEquals(3, integers.occurrencesOf(3));Assert.assertEquals(4, integers.occurrencesOf(4)); |
Резюме
В этом блоге я объяснил стратегию развития зрелой библиотеки коллекций Java. Мы рассматриваем следующие аспекты: сценарий использования, утилита и API, ковариантные переопределения, необходимые перегрузки и, наконец, симметрия.
сноска
Это личная цель — получить 1000 звезд в нашем проекте GitHub , поэтому, если вам нравится среда, продемонстрируйте свою поддержку и поставьте звезду в хранилище.
| Опубликовано на Java Code Geeks с разрешения Nikhil Navidadekar , партнер нашей программы JCG . Смотрите оригинальную статью здесь: API дизайн коллекций Eclipse Мнения, высказанные участниками Java Code Geeks, являются их собственными. |