Я хочу вернуть два объекта из метода Java, и мне было интересно, что может быть хорошим способом сделать это?
Возможные пути я могу думать о том, являются: Вернуть HashMap
(поскольку эти два объекта связаны) или возвращать ArrayList
из Object
объектов.
Чтобы быть более точным, два объекта, которые я хочу вернуть, являются (а) List
объектами и (б) разделенными запятыми именами одного и того же.
Я хочу вернуть эти два объекта из одного метода, потому что я не хочу перебирать список объектов, чтобы получить имена через запятую (что я могу сделать в том же цикле в этом методе).
Так или иначе, возвращение HashMap
не выглядит очень элегантным способом сделать это.
List
ссылка и своего рода таблица поиска.Ответы:
Если вы хотите вернуть два объекта, вы обычно хотите вернуть один объект, который вместо этого инкапсулирует два объекта.
Вы можете вернуть список
NamedObject
объектов следующим образом:Тогда вы можете легко вернуть
List<NamedObject<WhateverTypeYouWant>>
.Также: Почему вы хотите вернуть список имен через запятую вместо a
List<String>
? Или, еще лучше, вернуть aMap<String,TheObjectType>
с ключами, являющимися именами и значениями объектов (если ваши объекты не имеют заданный порядок, в этом случае aNavigableMap
может быть тем, что вы хотите.источник
Если вы знаете, что собираетесь вернуть два объекта, вы также можете использовать общую пару:
Отредактируйте более полностью сформированную реализацию вышеупомянутого:
Примечания, в основном о ржавчине с Java и дженерики:
a
иb
неизменны.makePair
Статический метод помогает вам с типизацией котельной пластины, что сделает бриллиантовый оператор в Java 7 менее раздражающим. Есть некоторая работа, чтобы сделать этот действительно хороший re: generics, но теперь все должно быть в порядке. (см. PECS)hashcode
иequals
генерируются затмением.cast
методе в порядке, но не совсем правильно.isInstance
, нужны ли подстановочные знаки в .источник
Pair
реализация. Одно небольшое изменение, которое я хотел бы сделать: добавить сообщение вClassCastException
. В противном случае отладка становится кошмаром, если по какой-то причине это не удается. (и rawtypes Подавить-предупреждения были бы не нужны , если бы вы бросили наPair<?,?>
(который работает, потому что вам нужно толькоObject
методы отa
иb
) Вы не возражаете , если я настроить код.?Если метод, который вы вызываете, является приватным или вызывается из одного места, попробуйте
Звонящий выглядит так:
Пример Pair от David Hanak не имеет синтаксического преимущества и ограничен двумя значениями.
И абонент выглядит так:
источник
Pair<T1, T2>
,Tuple<T1, T2, T3>
,Tuple<T1, T2, T3, T4>
И т.д. Затем конкретного использования показывает количество и типы параметровPair<int, String> temp = ...
или любой другой .Вы можете использовать любой из следующих способов:
1) Использование массива
2) Использование ArrayList
3) Использование HashMap
4) Использование вашего собственного класса контейнера
5) Использование AbstractMap.simpleEntry
6) Использование пара из Apache Commons
источник
Я почти всегда определяю классы n-Tuple, когда пишу код на Java. Например:
Я знаю, что это немного уродливо, но это работает, и вам просто нужно определить типы кортежей один раз. Кортежи - это то, чего на самом деле не хватает Java.
РЕДАКТИРОВАТЬ: пример Дэвида Ханака является более элегантным, поскольку он избегает определения геттеров и по-прежнему сохраняет объект неизменным.
источник
До Java 5 я бы согласился с тем, что решение Map не является идеальным. Это не даст вам проверку типа времени компиляции, поэтому может вызвать проблемы во время выполнения. Однако в Java 5 у нас есть универсальные типы.
Итак, ваш метод может выглядеть так:
MyType, конечно, является типом объекта, который вы возвращаете.
По сути, я думаю, что возвращение Map является правильным решением в этом случае, потому что это именно то, что вы хотите вернуть - отображение строки в объект.
источник
В качестве альтернативы, в ситуациях, когда я хочу вернуть несколько вещей из метода, я иногда буду использовать механизм обратного вызова вместо контейнера. Это очень хорошо работает в ситуациях, когда я не могу указать заранее, сколько объектов будет сгенерировано.
С вашей конкретной проблемой это будет выглядеть примерно так:
источник
java
, если у вас есть объектA
вызова объектаB.getResult()
иB.getResult()
вызовыA.finishResult()
как acallback
, объектB
получает сборщик мусора или он остается до завершения A? возможно глупый вопрос, но у меня есть фундаментальное замешательство!У Apache Commons есть кортеж и тройка для этого:
ImmutablePair<L,R>
Неизменная пара, состоящая из двух элементов Object.ImmutableTriple<L,M,R>
Неизменная тройка, состоящая из трех элементов Object.MutablePair<L,R>
Изменчивая пара, состоящая из двух элементов Object.MutableTriple<L,M,R>
Изменчивая тройка, состоящая из трех элементов Object.Pair<L,R>
Пара, состоящая из двух элементов.Triple<L,M,R>
Тройка, состоящая из трех элементов.Источник: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html.
источник
Хотя в вашем случае, комментарий может быть хорошим способом, в Android вы можете использовать
Pair
. Простоисточник
Использование следующего объекта Entry Пример:
источник
Что касается вопроса о множественных возвращаемых значениях в целом, я обычно использую небольшой вспомогательный класс, который переносит одно возвращаемое значение и передается методу в качестве параметра:
(для примитивных типов данных я использую небольшие вариации для непосредственного хранения значения)
Метод, который хочет вернуть несколько значений, будет объявлен следующим образом:
Возможно, основным недостатком является то, что вызывающий объект должен заранее подготовить возвращаемые объекты на тот случай, если он захочет их использовать (и метод должен проверять наличие нулевых указателей).
Преимущества (по сравнению с другими предлагаемыми решениями):
источник
Все возможные решения будут клуджами (такими как объекты-контейнеры, ваша идея HashMap, «множественные возвращаемые значения», реализованные с помощью массивов). Я рекомендую восстановить разделенный запятыми список из возвращенного списка. Код в конечном итоге станет намного чище.
источник
Сохраняйте это простым и создайте класс для ситуации с несколькими результатами. В этом примере принимается ArrayList и текст сообщения из базы данныхhelper getInfo.
Где вы вызываете подпрограмму, которая возвращает несколько значений, которые вы кодируете:
В подпрограмме getInfo вы кодируете:
и определить класс multResult с помощью:
}
источник
На мой взгляд, здесь действительно три варианта, и решение зависит от контекста. Вы можете выбрать реализацию конструкции имени в методе, который создает список. Это выбор, который вы выбрали, но я не думаю, что он лучший. Вы создаете связь в методе источника с методом потребления, который не должен существовать. Другим абонентам может не потребоваться дополнительная информация, и вы будете рассчитывать дополнительную информацию для этих абонентов.
В качестве альтернативы вы можете заставить вызывающий метод вычислить имя. Если эта информация нужна только одному абоненту, вы можете на этом остановиться. У вас нет дополнительных зависимостей, и, хотя требуется немного дополнительных вычислений, вы избежали слишком специфического метода построения. Это хороший компромисс.
Наконец, вы могли бы сам список быть ответственным за создание имени. Это тот маршрут, по которому я бы пошел, если расчеты должны выполняться несколькими звонящими. Я думаю, что это возлагает ответственность за создание имен с классом, который наиболее тесно связан с самими объектами.
В последнем случае моим решением было бы создать специализированный класс List, который возвращает разделенную запятыми строку с именами объектов, которые он содержит. Сделайте класс достаточно умным, чтобы он создавал строку имени на лету, когда объекты добавляются и удаляются из него. Затем верните экземпляр этого списка и при необходимости вызовите метод генерации имени. Хотя может быть почти так же эффективно (и проще) просто отложить вычисление имен до первого вызова метода и затем сохранить его (отложенная загрузка). Если вы добавляете / удаляете объект, вам нужно только удалить вычисленное значение и пересчитать его при следующем вызове.
источник
Может сделать что-то вроде кортежа в динамическом языке (Python)
и использовать как это
источник
Я следовал подходу, аналогичному описанному в других ответах, с некоторыми изменениями, основанными на моих требованиях, в основном я создал следующие классы (на всякий случай, все на языке Java):
Затем мое требование было простым: в классе репозитория, который достигает БД, для методов Get, которые извлекают данные из БД, мне нужно проверить, не удалось или не получилось, а затем, в случае успеха, мне нужно поиграть с возвращающимся списком. , если не удалось, остановите выполнение и сообщите об ошибке.
Так, например, мои методы такие:
Где ResultMessage - это просто класс с двумя полями (код / сообщение), а Customer - это любой класс с кучей полей, поступающих из БД.
Затем, чтобы проверить результат, я просто делаю это:
источник
В C ++ (STL) есть парный класс для объединения двух объектов. В Java Generics парный класс недоступен, хотя на него есть спрос . Вы могли бы легко реализовать это самостоятельно, хотя.
Однако я согласен с некоторыми другими ответами, что если вам нужно вернуть два или более объектов из метода, было бы лучше инкапсулировать их в классе.
источник
Почему бы не создать
WhateverFunctionResult
объект, содержащий ваши результаты и логику, необходимую для анализа этих результатов, повторения и т. Д. Мне кажется, что либо:Я вижу, что такого рода проблемы возникают снова и снова. Не бойтесь создавать свои собственные классы контейнеров / результатов, которые содержат данные и связанные с ними функциональные возможности для обработки этого. Если вы просто передаете материал в виде
HashMap
или подобном, тогда ваши клиенты должны разбирать эту карту на части и получать содержимое каждый раз, когда они хотят использовать результаты.источник
источник
Это не совсем ответ на вопрос, но, поскольку каждое из приведенных здесь решений имеет некоторые недостатки, я предлагаю немного реорганизовать ваш код, поэтому вам нужно вернуть только одно значение.
Дело первое.
Вам нужно что-то внутри, а также за пределами вашего метода. Почему бы не вычислить это снаружи и передать это методу?
Вместо того:
Пытаться:
Это должно охватывать большинство ваших потребностей, так как в большинстве ситуаций одно значение создается раньше другого, и вы можете разделить их на два метода. Недостатком является то, что метод
createThingsB
имеет дополнительный параметр по сравнению сcreateThings
, и, возможно, вы передаете точно один и тот же список параметров дважды различным методам.Случай второй.
Наиболее очевидное решение и упрощенная версия первого случая. Это не всегда возможно, но, может быть, оба значения могут быть созданы независимо друг от друга?
Вместо того:
Пытаться:
Чтобы сделать его более полезным, эти два метода могут иметь общую логику:
источник
Передайте список своему методу и заполните его, затем верните строку с именами, например так:
Тогда назовите это так:
источник
Я использовал очень простой подход для решения проблем множественных возвратов. Он служит цели и избегает сложности.
Я называю это подходом с разделителем строк
И он эффективен, так как может даже возвращать значения нескольких типов, например, int, double, char, string и т. Д.
В этом подходе мы используем строку, которая вряд ли будет встречаться вообще. Мы называем это разделителем. Этот разделитель будет использоваться для разделения различных значений при использовании в функции
Например, мы получим наш окончательный возврат как (например) разделитель intValue разделитель doubleValue ... И затем, используя эту строку, мы получим всю необходимую информацию, которая также может иметь различные типы.
Следующий код покажет работу этой концепции
Используется разделитель ! @ # И возвращаются 3 значения intVal, doubleVal и stringVal
ВЫВОД
источник
В C вы могли бы сделать это, передав указатели на заполнители для результатов в качестве аргументов:
Давайте попробуем нечто подобное, на Java.
источник
ПРОЙДИТЕ ХАШ В МЕТОД И ПОПУЛЯЙТЕ ЕГО ......
public void buildResponse (String data, Map response);
источник