Разве Java не имел класса Pair?

Помню ли я неправильно, или Java, когда-то, предоставлял класс Pair как часть своего API?

Ответ 1

В стандартной структуре нет пары, но Apache Commons Lang, которая приближается к "стандарту", имеет Pair.

Ответ 2

Java 1.6 и upper имеют две реализации интерфейса Pair (Map.Entry): AbstractMap.SimpleEntry и AbstractMap.SimpleImmutableEntry

Я использую его, когда вам нужно хранить пары (например, размер и сбор объектов).

Этот фрагмент из моего производственного кода:

public Map<L1Risk, Map.Entry<int[], Map<L2Risk, Map.Entry<int[], Map<L3Risk, List<Event>>>>>>
        getEventTable(RiskClassifier classifier) {
    Map<L1Risk, Map.Entry<int[], Map<L2Risk, Map.Entry<int[], Map<L3Risk, List<Event>>>>>> l1s = new HashMap<>();
    Map<L2Risk, Map.Entry<int[], Map<L3Risk, List<Event>>>> l2s = new HashMap<>();
    Map<L3Risk, List<Event>> l3s = new HashMap<>();
    List<Event> events = new ArrayList<>();
    ...
    map.put(l3s, events);
    map.put(l2s, new AbstractMap.SimpleImmutableEntry<>(l3Size, l3s));
    map.put(l1s, new AbstractMap.SimpleImmutableEntry<>(l2Size, l2s));
}

Код выглядит сложным, но вместо Map.Entry вы ограничиваетесь массивом объекта (размером 2) и теряете проверки типа...

Ответ 3

A Класс пары:

public class Pair<K, V> {

    private final K element0;
    private final V element1;

    public static <K, V> Pair<K, V> createPair(K element0, V element1) {
        return new Pair<K, V>(element0, element1);
    }

    public Pair(K element0, V element1) {
        this.element0 = element0;
        this.element1 = element1;
    }

    public K getElement0() {
        return element0;
    }

    public V getElement1() {
        return element1;
    }

}

использование:

Pair<Integer, String> pair = Pair.createPair(1, "test");
pair.getElement0();
pair.getElement1();

Неизменяемость, только пара!

Ответ 4

Здесь много реализации, но все время чего-то не хватает, переопределение метода с равным и хеш-кодом.

вот более полная версия этого класса:

/**
 * Container to ease passing around a tuple of two objects. This object provides a sensible
 * implementation of equals(), returning true if equals() is true on each of the contained
 * objects.
 */
public class Pair<F, S> {
    public final F first;
    public final S second;

    /**
     * Constructor for a Pair.
     *
     * @param first the first object in the Pair
     * @param second the second object in the pair
     */
    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }

    /**
     * Checks the two objects for equality by delegating to their respective
     * {@link Object#equals(Object)} methods.
     *
     * @param o the {@link Pair} to which this one is to be checked for equality
     * @return true if the underlying objects of the Pair are both considered
     *         equal
     */
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Pair)) {
            return false;
        }
        Pair<?, ?> p = (Pair<?, ?>) o;
        return Objects.equals(p.first, first) && Objects.equals(p.second, second);
    }

    /**
     * Compute a hash code using the hash codes of the underlying objects
     *
     * @return a hashcode of the Pair
     */
    @Override
    public int hashCode() {
        return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
    }

    /**
     * Convenience method for creating an appropriately typed pair.
     * @param a the first object in the Pair
     * @param b the second object in the pair
     * @return a Pair that is templatized with the types of a and b
     */
    public static <A, B> Pair <A, B> create(A a, B b) {
        return new Pair<A, B>(a, b);
    }
}

Ответ 5

Это должно помочь.

Подводя итог: общий Pair класс не имеет специальной семантики, и вам может понадобиться класс Tripplet и т.д. Разработчики Java, таким образом, не включили общий Pair, но предлагают писать специальные классы (что не так сложно), как Point(x,y), Range(start, end) или Map.Entry(key, value).

Ответ 7

У многих сторонних библиотек есть свои версии Pair, но Java никогда не имел такого класса. Ближайшим является внутренний интерфейс java.util.Map.Entry, который предоставляет неизменяемое свойство ключа и возможно изменяемое значение.

Ответ 8

Если вы хотите, чтобы пара (не предположительно пара ключ-значение) не содержала двух общих данных, ни одно из вышеперечисленных решений не было действительно удобным, поскольку первый (или так называемый Key) не может быть изменен (ни в Apache Commons Lang Pair, ни в AbstractMap.SimpleEntry). У них есть свои собственные причины, но все же вам может потребоваться изменить оба компонента. Вот класс Pair, в котором оба элемента могут быть установлены

public class Pair<First, Second> {
    private First first;
    private Second second;

    public Pair(First first, Second second) {
        this.first = first;
        this.second = second;
    }

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

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

    public First getFirst() {
        return first;
    }

    public Second getSecond() {
        return second;
    }

    public void set(First first, Second second) {
        setFirst(first);
        setSecond(second);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Pair pair = (Pair) o;

        if (first != null ? !first.equals(pair.first) : pair.first != null) return false;
        if (second != null ? !second.equals(pair.second) : pair.second != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = first != null ? first.hashCode() : 0;
        result = 31 * result + (second != null ? second.hashCode() : 0);
        return result;
    }
}

Ответ 9

Кажется странным. Я нашел эту ветку, также думая, что видел ее в прошлом, но не смог найти ее в Джавадоке.

Я вижу, что разработчики Java используют специализированные классы и что наличие общего класса Pair может заставить разработчиков быть ленивыми (гибнуть мысль!)

Однако, по моему опыту, есть, несомненно, моменты, когда вещь, которую вы моделируете, - это всего лишь пара вещей и придумывание значимого имени для отношений между двумя половинами пары, на самом деле больнее, чем просто продолжай с этим. Поэтому вместо этого нам нужно создать класс "на заказ" практически кодового кода - вероятно, он называется "Пара".

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