Комментарии 30
Красивая схема классов. Я так понимаю, это IntellijIDEA генерирует такую?
+2
В английском нет такого слова «cortege» в математическом смысле. Есть «tuple».
+5
В простых случаях хватает org.apache.commons.collections.keyvalue.MultiKey из commons-collections
+1
Возможно и хватит. А если нужно больше 5-ти элементов? и MultiKey не имеет контроля типов элементов.
+1
Если брать не абстрактные примеры, то для такого случая уже стоило бы сделать класс для значения. (В общем-то, его иногда стоит сделать даже для 2-х элементов)
+1
В MultiKey можно хоть сколько объектов хранить. Контроля типов нет. Ну я и говорю в простых случаях.
+1
Я загрузил
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
И не увидел как можно сделать MultiKey длиней 5-ти элментов :(.
Возможно не так библиотека.
Но как альтернативу конечно тоже можно использовать.
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
И не увидел как можно сделать MultiKey длиней 5-ти элментов :(.
Возможно не так библиотека.
Но как альтернативу конечно тоже можно использовать.
+1
Cortege
не самое главно что мне хотелось показать. Если рассматривать Cortege
как банальный контейнер для цепочки объектов, то проще использовать простой массив. :)Более интересным с моей точки зрения является не кортеж, а коллекции CortegeSet и CortegeList.
Возможность использовать их как альтерантиву физической таблицы подобно как в реляционных базах, но в памяти.
Основной областью применения таких конструкций я вижу в первую очередь в случаях, когда нужно манипулировать с данными в таблице (искать, изменять, добавлять, удалять строки и/или элементы), но когда по окончанию жизненного цикла сама таблица больше не нужна (не сохраняется в базу данных). Например при формировании отчета.
+1
Писал когда-то похожую библиотеку, теперь жду от оракла включения project lambda в новую JDK.
+1
// создание инстанса кортежа:Понятно, что в рантайме такой информации вы и не получите напрямую. Но первое что приходит в голову (и подобным образом в таких случаях делается):
Cortege<Long, Cortege<String, Cortege.End>> cortegeLS = CortegeChain.create(2);
Следует обратить внимание на аргумент метода create. В связи с тем, что в Java дженерики существуют лишь на этапе компиляции, и добраться к ним в runtime я «законных» методов не нашел :(, пришлось «заплатить» за это такой ценой. Суть этого параметра — декларация глубины создаваемого кортежа. Но в виду того, что разработчик как правило знает кол-во элементов, необходимость указания этого параметра не должно вызывать больших проблем.
примечание: Но все же, если кто-то может предложить свое решение это проблемки с параметром — я буду чрезвычайно благодарен.
Cortege<Long, Cortege<String, Cortege.End>> cortegeLS = CortegeChain.create(Long.class,String.class);
, соответственно create какая-то такая:create(Class... c)
, и далее внутри вашего кортежа храните всю эту же информацию о типах, потом можно дёргать и по индексу и прочее, что вы описали ниже. Нет?+1
Я именно о таком решении уже думал, но пока не решился на включение его в релиз:
Действительно, осуществлять проверку в runtime можно будет достаточно легко.
Но есть два минуса:
1. декларация кортежа более трех элементов (основная область применения) будет очень длинной :(
2. к сожалению проверка будет только на runtime мне кажется этого мало, хочется придумать красивое и компактное решение для котроля на этапе компиляции.
Но я полностью с Вами согласен, что предложеное решение позволит повысить контроль над типами. Очень возможно что в следующий релиз войдет Ваше решение. Спасибо.
Cortege<Long, Cortege<String, Cortege.End>> cortegeLS = CortegeChain.create(Long.class,String.class);
Действительно, осуществлять проверку в runtime можно будет достаточно легко.
Но есть два минуса:
1. декларация кортежа более трех элементов (основная область применения) будет очень длинной :(
2. к сожалению проверка будет только на runtime мне кажется этого мало, хочется придумать красивое и компактное решение для котроля на этапе компиляции.
Но я полностью с Вами согласен, что предложеное решение позволит повысить контроль над типами. Очень возможно что в следующий релиз войдет Ваше решение. Спасибо.
+1
Для этапа компиляции по-любому надо дополнительно параметризовать генериками сам метод create. Это два несвязанных случая. Но ведь и сейчас он у вас совершенно без всякого контроля типов возвращает кортеж. Или я чего-то не понял?
0
Да, Вы правы, усилить контроль над типами элеменентов кортежа стоит. Ваше предложение на счет
На счет:
Не везде контроль отсутствует. Если брать элементы поочередно методом
Отсутствует контроль, когда происходит обращение к элементу по индексу как в
create(Class<? extends Object>... types)
разумно. Но опять же остаются грустные случаи когда программист сможет продекларировать кортеж с одним набором типов и кол-вом элементов, но вызвать приэтом метод create с совершенно иным набором типов и их кол-вом. Приведу пример:Cortege<Long, Cortege<String, Cortege.End>> cortegeLS = CortegeChain.create(Character.class, Integer.class, String.class);
Я к сожелению не могу придумать как проверить такую ситуацию на этапе компиляции. :( Если Вы можете подсказать решение, буду очень благодарен.На счет:
Но ведь и сейчас он у вас совершенно без всякого контроля типов возвращает кортеж. Или я чего-то не понял?
Не везде контроль отсутствует. Если брать элементы поочередно методом
getValue()
тип контролируется на этапе компиляции.Отсутствует контроль, когда происходит обращение к элементу по индексу как в
getValue(int index)
.0
Не везде контроль отсутствует. Если брать элементы поочередно методом getValue() тип контролируется на этапе компиляции.Это то понятно, там у вас в некоторых местах так и пишется в комментариях «с контролем типа». Я имею в виду именно сам метод create у вас возвращает бесконтрольный на этапе компиляции объект.
0
Да, Вы правы:
С контролем типов есть большие трудности. Мне очевидно следует полностью пересмотреть идею хранения и контроля типов в кортеже. Это была первая, но возможна не самая удачная попытка. Именно для того чтобы как можно полней осознать все за и против этого способа храннеия кортежа я и вынес на обсуждение эту тему. Но с моей точки зрения всеже есть и явные «фишки» у такого рекурсивной способа описания структуры. Возможно кому-то будет удобно его применить совершенно в другой области. :)
Всеже справедливости ради надо сказать, что все так сконцентрировались на кортеже, но практически никто не смотрел на коллекции. В них собственно и весь «сахар» (я же писал о методах findAny и extract). В следующей версии скорее всего будет другая сруктура у кортежа, но то, что получилось сделать в коллекциях я постараюсь сохранить.
Я имею в виду именно сам метод create у вас возвращает бесконтрольный на этапе компиляции объект.
С контролем типов есть большие трудности. Мне очевидно следует полностью пересмотреть идею хранения и контроля типов в кортеже. Это была первая, но возможна не самая удачная попытка. Именно для того чтобы как можно полней осознать все за и против этого способа храннеия кортежа я и вынес на обсуждение эту тему. Но с моей точки зрения всеже есть и явные «фишки» у такого рекурсивной способа описания структуры. Возможно кому-то будет удобно его применить совершенно в другой области. :)
Всеже справедливости ради надо сказать, что все так сконцентрировались на кортеже, но практически никто не смотрел на коллекции. В них собственно и весь «сахар» (я же писал о методах findAny и extract). В следующей версии скорее всего будет другая сруктура у кортежа, но то, что получилось сделать в коллекциях я постараюсь сохранить.
0
Хм. А вот авторы Guava: Google Core Libraries против кортежей. Пишут, что:
code.google.com/p/guava-libraries/wiki/IdeaGraveyard#Tuples_for_n_%3E=_2
И правда, пара пар трех кортежей двух пар звучит зловеще:)
Tuple types are awful obfuscators. Tuples obfuscate what the fields actually mean (getFirst and getSecond are almost completely meaningless), and anything known about the field values. Tuples obfuscate method signatures: ListMultimap<Route, Pair<Double, Double>> is much less readable than ListMultimap<Route, LatLong>.
code.google.com/p/guava-libraries/wiki/IdeaGraveyard#Tuples_for_n_%3E=_2
И правда, пара пар трех кортежей двух пар звучит зловеще:)
+8
Я более чем согласен. В большинстве своем — это тупо лень разрабочика создавать новый класс с читаемыми названиями (даже внутренний статический).
0
Согласен. Действительно есть трудность с пониманием смысла значения хронящегося в какой-либо позиции. Особенно когда тип элементов часто повторяется. Например,
Конечно лучше когда есть контейнер с вразумительными геттерами.
Но в некоторых случаях может понадобиться получить фрагмент кортежа и рассматривать его как самостоятельную сущность.
Опять же, стоит обратить внимание на инструментарий, который дают имплементации коллекций как:
Cortege<Long, Cortege<Long, Cortege<Long, Cortege.End>>> cortegeLLS = CortegeChain.create();
Конечно лучше когда есть контейнер с вразумительными геттерами.
Но в некоторых случаях может понадобиться получить фрагмент кортежа и рассматривать его как самостоятельную сущность.
Cortege
как в примере, Cortege<Long, Cortege<Long, Cortege.End>> rightCortegeLS = cortegeLLS.nextElement();
Опять же, стоит обратить внимание на инструментарий, который дают имплементации коллекций как:
CortegeSet
и CortegeList
. В посте есть пример использование некоторых возможностей. Например, найти подколлекцию по значению элемента в кортежах или по предикату. (методы findAny и extract)Cortege<Long, Cortege<Long, Cortege<String, Cortege.End>>> any5 = cortegeSetLLS.findAny(1, 5L);
илиCortegeSet<Cortege<Long, Cortege<Long, Cortege<String, Cortege.End>>>> extractAll5 = cortegeSetLLS.extract(1, 5L);
0
НЛО прилетело и опубликовало эту надпись здесь
Мне честно очень жаль, что Ваша грусть столь велика.
Но мне кажется Вы привели не совсем честный пример, отношение к которому не имеет моя библиотека. Я какраз хотел уйти от подобный кашмарных выражений типа
Конечно отчасти Ваше замечание на счет громоздкости декларации кортежа справедливо, на данный момент я еще не придумал более компактной формы декларации типов, без потери неограниченности длины кортежа.
Но мне кажется Вы привели не совсем честный пример, отношение к которому не имеет моя библиотека. Я какраз хотел уйти от подобный кашмарных выражений типа
Pair<List<Quadruple<String, String, String, String>>
Но конечно же я не могу с Вами не согласиться в том, что название интрефейса Cortege
возможно не очень удачно. Обязуюсь отнестись к Вашему замечанию серъезно и постараться решить этот вопрос.Конечно отчасти Ваше замечание на счет громоздкости декларации кортежа справедливо, на данный момент я еще не придумал более компактной формы декларации типов, без потери неограниченности длины кортежа.
-1
pastebin.com/xzJamfC0
Посмотрите как мы доставали дженерики в рантайме. Надеюсь поможет: )
За статью пятерочка
Посмотрите как мы доставали дженерики в рантайме. Надеюсь поможет: )
За статью пятерочка
-1
О боги, какой кошмар. Вот именно из-за таких примеров над нами, яверами, и издеваются за наши громоздкие конструкции поверх всего.
Смысл кортежа для программиста — это удобный способ передать или хранить пачку значений. Синтаксический сахар, ведь всегда же можно под конкретный набор передаваемых типов создать класс вроде РезультатМетодаА. И вот ваш синтаксический сахар, он еще и совсем не сладкий, он мало того что горький (нечитаемый), так еще и глубоко теоретический. Вот зачем, зачем вам понадобилось вот это условие:
Кому от этого станет лучше? Часто вы в своей практике передавали кортежи длиной в 10 элементов? Если и да, то это место, которому точно помог бы рефакторинг.
Короче, я вот к чему. Код с использованием такой конструкции неудобен (.nextElement().nextElement()? правда? и это при заявленной неограниченной длине? что за лапша с ним станет при длине кортежа, скажем, в 20?) и, что хуже, не читаем. Решения, просто дающие ограниченный набор шаблонных классов ограниченной длины (будь то Pair, Triplet, etc., или Tuple2, Tuple3, Tuple10 и т.д.) куда как удобнее в использовании, не удовлетворяя при этом единственному, глубоко теоретическому условию.
А главное, все так аккуратно и точно сделано, залюбуешься. Эту бы энергию да на мирные цели…
Смысл кортежа для программиста — это удобный способ передать или хранить пачку значений. Синтаксический сахар, ведь всегда же можно под конкретный набор передаваемых типов создать класс вроде РезультатМетодаА. И вот ваш синтаксический сахар, он еще и совсем не сладкий, он мало того что горький (нечитаемый), так еще и глубоко теоретический. Вот зачем, зачем вам понадобилось вот это условие:
Кортеж должен быть неограниченным по длине и типу
Кому от этого станет лучше? Часто вы в своей практике передавали кортежи длиной в 10 элементов? Если и да, то это место, которому точно помог бы рефакторинг.
Короче, я вот к чему. Код с использованием такой конструкции неудобен (.nextElement().nextElement()? правда? и это при заявленной неограниченной длине? что за лапша с ним станет при длине кортежа, скажем, в 20?) и, что хуже, не читаем. Решения, просто дающие ограниченный набор шаблонных классов ограниченной длины (будь то Pair, Triplet, etc., или Tuple2, Tuple3, Tuple10 и т.д.) куда как удобнее в использовании, не удовлетворяя при этом единственному, глубоко теоретическому условию.
А главное, все так аккуратно и точно сделано, залюбуешься. Эту бы энергию да на мирные цели…
+4
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Кортежи объектов в Java и их коллекции