7

Каков эквивалент C++ Pair<L,R> в Java?

33

Есть ли какая-то веская причина, почему в Java нет класса Pair<L,R>? Какой эквивалент этому конструкцию из C++? Я бы предпочел избежать реализации собственного варианта.

Кажется, что в версии 1.6 появилась нечто похожее - AbstractMap.SimpleEntry<K,V>, но это выглядит довольно запутанно.

5 ответ(ов)

1

Это Java. Вам нужно создать собственный класс Pair с описательными именами классов и полей, и не беспокоиться о том, что вы будете переизобретать колесо, реализуя методы hashCode()/equals() или снова и снова реализуя интерфейс Comparable.

1

Вот пример класса Pair, совместимого с HashMap в Java. Данный класс позволяет хранить пару значений и переопределяет методы hashCode() и equals(), что делает его подходящим для использования в коллекциях, таких как HashMap.

public class Pair<A, B> {
    private A first;
    private B second;

    public Pair(A first, B second) {
        super();
        this.first = first;
        this.second = second;
    }

    @Override
    public int hashCode() {
        int hashFirst = first != null ? first.hashCode() : 0;
        int hashSecond = second != null ? second.hashCode() : 0;

        return (hashFirst + hashSecond) * hashSecond + hashFirst;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Pair) {
            Pair<?, ?> otherPair = (Pair<?, ?>) other;
            return 
            ((this.first == otherPair.first ||
                (this.first != null && otherPair.first != null &&
                  this.first.equals(otherPair.first))) &&
             (this.second == otherPair.second ||
                (this.second != null && otherPair.second != null &&
                  this.second.equals(otherPair.second)))) ;
        }

        return false;
    }

    @Override
    public String toString() { 
        return "(" + first + ", " + second + ")"; 
    }

    public A getFirst() {
        return first;
    }

    public void setFirst(A first) {
        this.first = first;
    }

    public B getSecond() {
        return second;
    }

    public void setSecond(B second) {
        this.second = second;
    }
}

Объяснение:

  • Переопределение hashCode(): Этот метод рассчитывает хеш-код на основе хеш-кодов обоих элементов. Это важно для того, чтобы объекты Pair корректно работали как ключи в HashMap.

  • Переопределение equals(): Этот метод проверяет, равны ли две пары. Он учитывает как null значения, так и значения объектов. Если оба значения совпадают, пары равны.

  • Методы доступа (getFirst(), getSecond(), setFirst(), setSecond()): Эти методы позволяют удобно работать с элементами пары, не нарушая инкапсуляцию.

Данный класс будет полезен в случаях, когда необходимо хранить совпадающие элементы в виде пар и использовать их в коллекциях, таких как HashMap.

0

Apache Commons Lang 3.0 и новее предоставляет несколько классов Pair, которые можно найти в пакете org.apache.commons.lang3.tuple. Это делается для удобной работы с парами значений.

Основные классы, которые предоставляются, включают Pair, ImmutablePair и MutablePair. Каждый из этих классов имеет свои особенности:

  1. Pair - это абстрактный базовый класс, который реализует общее поведение для пар.

  2. ImmutablePair - это класс, который представляет пару значений, оба из которых неизменяемы. Когда вы создаете экземпляр ImmutablePair, значения не могут быть изменены после создания.

  3. MutablePair - этот класс позволяет изменять значения пар. Вы можете установить новые значения для обоих элементов после создания.

Для получения дополнительной информации и документации о том, как использовать эти классы, вы можете обратиться к официальной документации Apache Commons Lang.

Если у вас есть конкретный вопрос о том, как использовать классы Pair или о их функциональности, не стесняйтесь задавать его!

0

Если вы ищете другой способ реализации класса Pair, то вот пример, который отвечает вашим требованиям:

  1. Публичные неизменяемые поля, т.е. простая структура данных.
  2. Реализует интерфейс Comparable.
  3. Простая реализация методов hashCode и equals.
  4. Простая фабричная функция, позволяющая не указывать типы, например: Pair.of("hello", 1);

Вот код для класса Pair:

public class Pair<FIRST, SECOND> implements Comparable<Pair<FIRST, SECOND>> {

    public final FIRST first;
    public final SECOND second;

    private Pair(FIRST first, SECOND second) {
        this.first = first;
        this.second = second;
    }

    public static <FIRST, SECOND> Pair<FIRST, SECOND> of(FIRST first, SECOND second) {
        return new Pair<FIRST, SECOND>(first, second);
    }

    @Override
    public int compareTo(Pair<FIRST, SECOND> o) {
        int cmp = compare(first, o.first);
        return cmp == 0 ? compare(second, o.second) : cmp;
    }

    // Может быть вынесен в вспомогательный класс.
    private static int compare(Object o1, Object o2) {
        return o1 == null ? (o2 == null ? 0 : -1) : (o2 == null ? 1 : ((Comparable) o1).compareTo(o2));
    }

    @Override
    public int hashCode() {
        return 31 * hashcode(first) + hashcode(second);
    }

    // Может быть вынесен в вспомогательный класс.
    private static int hashcode(Object o) {
        return o == null ? 0 : o.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Pair))
            return false;
        if (this == obj)
            return true;
        return equal(first, ((Pair) obj).first) && equal(second, ((Pair) obj).second);
    }

    // Может быть вынесен в вспомогательный класс.
    private boolean equal(Object o1, Object o2) {
        return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
    }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ')';
    }
}

Этот класс является универсальным и может использоваться для хранения пары значений с возможностью их сравнения, проверки на равенство и вычисления хеш-кода. Если у вас есть дополнительные вопросы или вам нужны доработки, дайте знать!

0

Вы можете рассмотреть библиотеку javatuples, которая, как я считаю, очень полезна.

Она предоставляет классы для работы с кортежами от одного до десяти элементов:

Unit<A> (1 элемент)
Pair<A,B> (2 элемента)
Triplet<A,B,C> (3 элемента)
Quartet<A,B,C,D> (4 элемента)
Quintet<A,B,C,D,E> (5 элементов)
Sextet<A,B,C,D,E,F> (6 элементов)
Septet<A,B,C,D,E,F,G> (7 элементов)
Octet<A,B,C,D,E,F,G,H> (8 элементов)
Ennead<A,B,C,D,E,F,G,H,I> (9 элементов)
Decade<A,B,C,D,E,F,G,H,I,J> (10 элементов)

Это может быть полезно, если вам нужно работать с фиксированными группами данных.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь