Какой лучший способ вернуть пару значений в Java?

Это небольшая проблема, так как я мог легко взломать класс пары, чтобы выполнить эту работу. Я действительно не хочу этого делать, и я чувствую, что должен быть простой, встроенный, похожий на Java способ возврата двух значений. Что вы, ребята, лучший и самый простой способ сделать это? Массивы? Некоторая другая структура данных?

Ответ 1

Насколько я знаю, к сожалению, нет встроенного представления пары в Java (и я, конечно же, пожелал, чтобы это было). Лично, когда я кодирую проект, где я нахожу, что парный класс часто будет полезен, я создаю общий класс Pair<T, U> (что, вероятно, вы так думали). Возвращение массива является быстрым и простым способом, но вы можете пожалеть об этом позже, потому что люди, которые используют ваш метод, задаются вопросом, может ли метод в какой-то момент вернуть более двух значений.

Какое бы решение вы ни выбрали: всякий раз, когда вы чувствуете, что вам нужна пара, вы должны подумать о том, сохранилось ли сегодня время с помощью, например, общий класс Pair действительно стоит потеря информации для следующего человека, который читает код (и этот человек вполне может быть вам через полгода). Написание отдельного класса для типа возвращаемого значения занимает больше времени, но оно будет передавать больше информации тем, кто использует ваш метод (а именно, он сообщает пользователям, что представляет собой возвращаемое значение, и содержит полезные имена участников для двух значений). Если это непубличный метод, который используется только в нескольких местах, пара, более приемлемая.

Ответ 2

Использование класса контейнера является самым простым способом.

 public class Pair<T, U> {         
    public final T t;
    public final U u;

    public Pair(T t, U u) {         
        this.t= t;
        this.u= u;
     }
 }

Ответ 3

Самое близкое, что я видел к "паре" в стандартных библиотеках, это интерфейс Map.Entry и AbstractMap.SimpleEntry и AbstractMap.SimpleImmutableEntry классы, которые его реализуют.

Если оба объекта являются одним и тем же классом, массив проще в использовании.

Ответ 4

Apache Commons Lang3 предоставляет абстрактный класс Pair с несколькими реализациями, включая ImmutablePair и MutablePair.

Ответ 5

Три подхода, все не так велики:

  • Создайте собственный Pair<A, B>. Вы сказали, что не хотите этого делать.
  • Верните a Object[]. Это не безопасный тип.
  • Мимические переменные или указатели, поставляя массивы одиночных элементов в качестве параметров.

Пример # 3:

public boolean getUserDetails(String userId, String[] lastName, String[] firstName, Date[] dob) {
  assert lastName  != null && lastName.length  == 1;
  assert firstName != null && firstName.length == 1;
  assert dob       != null && dob.length       == 1;
  ...
}

Третий вариант делает жизнь болезненной для вызывающего.

Так, как я уже сказал, никакого приятного решения.

В стороне, Scala использует различные классы Tuple (до 21 кортежа, из того, что я помню), чтобы помочь вам в этом.

Ответ 6

Мне сказали эксперты, что, столкнувшись с вопросом о парах, одна из двух вещей верна:

  • Вам нужно переосмыслить свою структуру (этот тупой ответ никому не помогает)
  • Вам нужно создать собственный класс для хранения пары

Я бы предположил, что второй случай не является настолько ненормальным. Однако, если то, что вы делаете, кажется слишком тривиальным для введения нового класса, то использование Map может работать, как предложили другие. Если вы просто отправляете один ответ назад, то Map выглядит немного.

Если список пар звучит так, как будто он будет работать, и вам нужно поддерживать порядок, вы можете попробовать LinkedHashMap, чтобы поддерживать порядок.

Ответ 7

Некоторые мои наблюдения:

  • Массив - это пугающий, быстрый и простой в использовании, хотя и невозможный для расширения его возможностей. Что делать, если вы хотите вернуть 3 значения через 3 месяца?

  • ArrayList/другие colletions могут быть хорошими, позволяет увеличить емкость (изначально 10). Обратите внимание, что Vector может быть излишним по сравнению с ArrayList, когда вы хотите сохранить только 2 значения, которые будут выбраны позже. Карта также может быть хорошей, потому что она всегда сортируется и упорядочивается.

  • Определенный пользователем класс: возможно, опция if имеет смысл (означает, что возвращаемые данные важны, а именно, как Java Bean), и вы хотите хранить в нем не более двух целых чисел. Читаемость лучше, если вы добавите в свой Javadoc больше заметок. Может быть расширен, как вам нравится, просто добавьте поля в этот класс. Медленнее, но безопаснее.

Ответ 8

В JavaFX есть пара классов, но вы не должны его использовать. То, что вы ДОЛЖНЫ использовать, выглядит примерно так:

// We've skipped imports and package declarations
public final class YourClass {
  /* Assume there is a bunch of stuff here */

  // I don't know what method you're using, so forgive the silly example
  public YourClass.Pair sillyExampleOfPairs(String someString) {
    return new YourClass.Pair(someString, someString.length() * 13);
  }

  @Value // Lombok annotation.
  public static class Pair {
    String text;
    int integer;
  }

  // this is an even more succinct possibility
  @Value public static final class ShorterPair {String text; int integer}
}

В то время как имя Пара здесь явно не так хорошо выбрано, и вы должны выбрать более описательное имя, очевидные способы его работы (поля являются окончательными частными и у вас есть геттер для каждого из-за аннотации) не должны быть потеряны для вас. И хотя да, это немного более многословие, чем использование пары, это гораздо более надежное. Что делать, если вам нужно добавить дополнительный параметр к возвращаемому значению? Вы "только" должны изменить этот класс. И вы можете сразу обновить все соответствующие JavaDocs, что тоже приятно. Если вам нужно изменить типы, они оба повлекут за собой аналогичный объем работы.

Пока вы только добавляете материал, старые методы getText() и getInteger() будут работать так же, как и раньше. Вы также избегаете добавлять к своим проектам еще одну зависимость. Это не большая победа. Наличие пары доступно для прототипирования, но это не приятно в дальнейшем.

Мой последний теоретический аргумент CS-y состоит в том, что Pair - это тот же тип, что и Pair. Но если у вас есть Phonebook.Entry(с String и int) и скажите, Inventory.Item(с именем и рядом элементов, которые мы в настоящее время инвентаризировали), эти два очень разных типа, которые делают очень разные вещи. Вы не можете поместить один в другой. Это хорошая вещь.

Нам также гораздо яснее для бедных ублюдков, которые должны пойти и отладить ваши системы, чтобы увидеть что-то вроде "com.name.project.something.something.Phonebook.Entry" в трассировке стека, чем "org.apache.commons". lang3.tuple.Pair". Один из них говорит мне, на что я должен смотреть, и дает мне информацию о том, ПОЧЕМУ Я вижу пару. Другой говорит... ничего.

Теперь вам может быть безразлично, что вам нужно набрать 3 дополнительных секунды, чтобы сэкономить мне 3 минуты. Но я предпочитаю верить в доброту твоего сердца и благородство твоей души. Поэтому, поступайте правильно.

Вместо этого напишите небольшой статический класс.

Ответ 9

если оба являются целыми числами, тогда я бы посоветовал java.awt.Point, но в противном случае просто создаю контейнерный класс с двумя объектами x и y