|
Модераторы: LSD, AntonSaburov |
|
Shklyar |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Почему в Set-е нету get-а?
--------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
Се ля ви |
|
|||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 8 Всего: 127 |
Индексации нет, порядку тоже нет. Что бы ты хотел, что бы такой метод выдавал?
-------------------- |
|||
|
||||
Shklyar |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Хотел бы по получить obj, который eq, приблизительно, как в Map получают значение.
Встретил ситуацию, когда часть обьекта определяет уникальность и ее легко повторить, а другая часть хранит дополнительные полезные данные, которые нужно получить. Можно проитерироваться, но пропадает вся прелесть хоть какой реализации Set. Это сообщение отредактировал(а) Shklyar - 17.7.2018, 08:40 --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
LSD |
|
|||
Leprechaun Software Developer Профиль Группа: Модератор Сообщений: 15709 Регистрация: 24.3.2004 Репутация: 209 Всего: 537 |
Тоже задавался таким вопросом, и пришел к выводу что такое использование Set это плохая практика. Ключ по которому ищут объект должен быть immutable, а вот вторая часть которая "хранит дополнительные полезные данные" явно выглядит как mutable часть. Получается, что ты создаешь объект пустышку заполненный наполовину, только для того чтобы использовать его как ключ. В данной ситуации лучше разделить объект на две части: key part и value part и использовать композицию, и соответственно данные хранить в Map. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
Се ля ви |
|
||||||||||||||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 8 Всего: 127 |
Довольно специфический функционал и вообще - это не корректное использование eq, IMHO (так что соглашусь с LSD)...
Но, как говориться, если нельзя, но очень хочется... )) В общем, если сильно нужно - добавь сам. Java, конечно, не Groovy, не Kotlin и тем более не Scala, что бы поддерживать из коробки extension-method`ы, но могу предложить два довольно корявых, но способа:
Для начала нам нужны зависимости на JUnit5, AssertJ (что бы делать проверки) и Lombok (без него, как, впрочем, и без Vavr`а, я уже давно - как без рук):
Ну и, что бы среда разработки лишний раз не ругалась на Lombok, желательно установить Lombok plugin. Правда, от всего это не спасёт - например, функционал @ExtensionMethod`а он не поддерживает - issue 21 до сих пор открыто :((( Так что придётся либо мириться с "краснотой" в IDE и code-review tool`е, либо использовать пока только первый способ. Итак, для начала нам нужен объект, по которому будем тестировать:
(Если в друг нет опыта с Lombok`ом, эти аннотации заставят перед компиляцией:
Итак, приступим. Первый вариант - использование неявной типизации при помощи ключевого слова var, появившегося в Java 10 (приём, известный как "Ad-Hock Methods" описан Николаем Парлогом тут):
Второй способ - через экспериментальную аннотацию @ExtensionMethod annotation-processor`а Lombok:
У меня все тесты проходят. Надеюсь, разъяснил. Демо-проект (в варианте с Gradle`ом) выложил на GitHub`е. -------------------- |
||||||||||||||
|
|||||||||||||||
Shklyar |
|
||||||||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Обьекты приходят снаружи, с зависимости. Раньше они были собраны в сет - видимо задумано им быть уникальными. Ранее достаточно было (и было) контейнс, но вот понадобилось посмотреть на обьект, который контейнс. Пришел к Map<T, T>
Интересная конструкция. Исходя из HotSpot имплементации Set, посчитал что получу свой поиск без дополнительных затрат перейдя на Map. Се ля ви, ого, почитаю. --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
||||||||
|
|||||||||
Shklyar |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Спасибо, есть с чем поиграться. Да, очень хочется, но не добавить, а взять. Где-то слышал, что самый надежный код - тот что не написан. Ну а если б хотелось написать, скорее б это был утилитный для сета класс. Посмотрел я метод get - а как там используется встроенный в Set алгоритм поиска?) И еще одно ПОЧЕМУ: почему метод сета add возвращает boolean? Забыл добавить, что такая конструкция понравилась как предохранитель, когда в будущем по неосторожности кто-то захочет что-то сломать. --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
Се ля ви |
|
||||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 8 Всего: 127 |
Никак, я по-простому накидал через монаду - просто что бы работало. Реализуй как надо - я же показывал исключительно как цеплять метод.
Так по сути это и есть второй мной описанный вариант - класс-то утильный с методом get отдельный и выносить можно куда угодно. Потому что в Set`е может уже быть этот объект - и это значит, что добавить (не удалив) его туда не получится. При чём определяется это по методам equals и hashCode, так что в твоём случае "странного" использования equals`а, это значит, что если там есть какой-то объект, который eq с тем, который ты пытаешься положить - ты его туда не положишь. Можно их, конечно, развести по hashCode`ам, но тогда ты теряешь преимущества того самого "встроенного в Set алгоритма поиска". -------------------- |
||||
|
|||||
Shklyar |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Не в моем. Вот посмотрел, и рад бы поругаться, да все тут ок.
Почему в мапе пут возврашает E? Про Lombok интересен такой вопрос: какие проблемы ты встречал или видишь системными? Слышал мнение, что кто-то долго парился с тем, что натворил Lombok. Я особо не встречал, максимум цикличность, которая детектится с первого раза. Как надо, пока, по моим представлениям, не получится. --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
Се ля ви |
|
||||||||||||||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 8 Всего: 127 |
equals - это проверка на эквивалентность, т.е. с т.з. предметной области - эти объекты - полные аналоги друг друга. То, что туда не обязаны входить все поля, означает, что они не значимы. Я сегодня могу одеть синюю майку, а завтра красную - но это всё равно останусь я и equals меня в синей майке со мной в красной должен выдавать true. Так же и тут - не вхождение полей в проверку по equals`у означает лишь то, что эти поля не являются идентифицирующими и не важны с т.з. предметной области задачи, но ожидания у програмиста, когда он видит, что два объекта equals именно такие - что это по сути один и тот же объект, просто в силу особенностей алгоритма решаемой задачи оказавшийся скопированным в различные области памяти. Это просто удобно, это т.н. pipeline-стиль написания кода. В Java он известен давно по классам StringBuilder/Buffer, но действительно активно применяется, начиная с Java 8 в Stream`ах, CompletableFuture`ах, Optional`ах - тебе нужно что-то сделать с объектом, но перед этим необходимо положить его в мапу по какому-то ключу. Если бы этого поведения не было, то ты кладёшь объект в мапу одной операцией, и только второй делаешь с ним то, что нужно - в итоге у тебя две операции вместо одной со всем сопутствующим гемороем - блок придётся ставить, если это в лямбде, внутри цикла или if`а, в тернарный оператор не воткнёшь... Очень громоздкий код получается и увеличивается количество точек, где можно совершить ошибку. Lombok - это не магия! Он простой, как топор и делает с твоим кодом совершенно очевидные, элементарные вещи по устранению boilerplate-кода (т.е. такого кода, за которым не стоит принятия решений, а он является тавтологией и его приходится писать просто из-за того, что язык этого требует). Уже достаточно давно был сформулирован принцип борьбы с таким кодом, который получил название "Convention over Configuration" ("Соглашения по конфикурации"), которому мы обязаны прогрессу в Computer Science последние лет 15, поскольку большинство новых разработок в Java-мире - Spring, Maven, Gradle, Lombok, Vavr, а так же языки и инструменты, проектировались в соответствии с этим принципом. Главное правило использования Lombok`а - как только тебе кажется, что Lombok делает что-то непонятное для тебя - применяешь действие "delombok" и смотришь, во что Lombok превратил твой код, пока не поймёшь. Большую часть деломбока вообще берёт на себя плагин к идее (просто кликаешь правой кнопкой мыши на классе и выбираешь Refactor -> Delombok -> {имя интересующей аннотации или "All lombok annotations" для всех}), но если аннотации в этом списке нет, можно использовать мавеновский плагин, вот моя конфигурация:
Посмотри доклад Цикура, он там конечно далеко не про всё рассказывает, но для начала сойдёт - https://youtu.be/VGewqN_x0oQ Что касается недостатков, они, опять же, сейчас (начиная с 10-й Java) теперь присущи и ей самой - это связано с т.н. "type inference" - когда ты вместо типа пишешь в простой Java var, а с lombok`ом - val. Дело в том, что с т.з. читабельности кода для человека это допустимо только в ситуации, когда из правой части выражения очевидна левая. Часто этим злоупотребляют и пишут val/var даже в тех случаях, когда при чтении кода непонятен выводимый из контекста тип переменной. Этого надо избегать. Один из разработчиков Java`ы Стюарт Маркс написал на этот счёт огромедную текстину, но если подытоживать, то практика должна быть такой: Используйте val/var только если верен хотя бы один пункт из списка:
Лично я только благодаря Lombok`у и Vavr`у в принципе способен ещё писать на Java, от которой без них меня уже просто тошнит. Если бы ты изучил другие языки JVM, типа Groovy, Kotlin`а и тем более Scala`ы, у тебя - поверь - было бы то же самое. И - да, в продакшене я и многие мои коллеги его использовал, использую и, конечно, буду использовать, пока на Java приходится писать. Работаю я старшим разработчиком в EPAM`е, если что - можешь на меня ссылаться. -------------------- |
||||||||||||||
|
|||||||||||||||
Shklyar |
|
||||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
--------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
||||
|
|||||
Се ля ви |
|
|||
Java/SOAрхитектор Профиль Группа: Модератор Сообщений: 2016 Регистрация: 5.6.2004 Где: place without tim e and space Репутация: 8 Всего: 127 |
Мда, ошибочка вышла... Я бы на месте разработчиков сделал бы по-другому. Ну тогда не так удобно, как могло бы. Добавлено через 3 минуты и 56 секунд Вообще, на коллекции в Java море критики - у того же Одерского (автор Scala`ы) - почему они с нуля свою библиотеку коллекций написали. Да и в Java многие активно юзают свои библиотеки коллекций - Guava, GoldmanSachs, Apache, Trove... тут поглядеть можно. -------------------- |
|||
|
||||
Shklyar |
|
|||
Бывалый Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: 2 Всего: 3 |
Собственно, да, ответы на мои почему нашел: потому что так сделали. Но было увлекательно поковырять про редко используемые особенности. --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
rfq |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 20.3.2007 Репутация: нет Всего: нет |
если посмотреть на `Set<T>` как на `Map` (в котором есть `get()`), то это `Map<T, boolean>`. То есть, подаем объект и в качестве ответа получаем - входит такой объект во множество или нет. Так что метод `get()` в `Set` есть, только называется он `contains()`. |
|||
|
||||
_zorn_ |
|
||||
Эксперт Профиль Группа: Завсегдатай Сообщений: 1077 Регистрация: 21.8.2007 Репутация: нет Всего: 12 |
А вот можно опять насрать на яву ?
Вот буквально сегодня надо было быстренько из с++ в qml данные передать. Я уж начал задумываться - это же писец, типы классы и вот это вот все создавать (воздействие явы на мозг). Но нет посмотрел на свой старый код и QVariantHash меня спас. Тупо
И из qml
Ну и нахрена эти сложности со сранным приведением типа ? И утил для конвертации ? Добавлено через 5 минут и 31 секунду Вот только не надо мне гнать что в вашем ынтерпрайзе нету архитектурных ошибок. В итоге вы боритесь с мельницами на ровном месте. |
||||
|
|||||
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |