Общий класс пары - PullRequest
       42

Общий класс пары

11 голосов
/ 18 мая 2011

Просто пытаясь ответить на этот вопрос, я нашел в прошлом экзаменационном листе, чтобы я мог подготовиться к предстоящему экзамену по Java.

Предоставление универсального класса Pair для представления пар вещей. Класс должен предоставлять конструктор, метод для получения первого члена пары, метод для получения второго члена пары, метод для установки первого члена пары, метод для установки второго члена пары , Класс должен быть параметризован по двум типам: один для первого члена и один для второго члена пары.

Это правильная реализация для этого вопроса?

public class Pair<firstThing, secondThing>{
   private firstThing first;//first member of pair
   private secondThing second;//second member of pair

   public Pair(firstThing first, secondThing second){
     this.first = first;
     this.second = second;
   }

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

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

   public thing getFirst() {
     return this.first;
   }

   public thing getSecond() {
     return this.second;
   }
}

Ответы [ 14 ]

17 голосов
/ 18 мая 2011

Почти.Я бы написал так:

public class Pair<F, S> {
    private F first; //first member of pair
    private S second; //second member of pair

    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }

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

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

    public F getFirst() {
        return first;
    }

    public S getSecond() {
        return second;
    }
}

Редактировать: я согласен с комментарием @ karmakaze.Код должен пропускать установщики и делать первый и второй финал, чтобы сохранить его неизменным.

10 голосов
/ 23 сентября 2013

Потребность в классе Pair обычно возникает в более крупных проектах - я собираюсь (повторно) реализовать его для текущего проекта (поскольку предыдущие реализации недоступны).

Обычно я делаю этонеизменный POJO, с удобной функцией для создания экземпляров.Например:

public class Pair<T,U>
{
    public final T first;
    public final U second;
    public static <T,U> Pair<T,U> of(T first, U second);
}

Чтобы конечный пользователь мог написать:

return Pair.of (a, b);

и

Pair<A,B> p = someThing ();
doSomething (p.first);
doSomethingElse (p.second);

Как упоминалось выше, класс Pair должен также реализоватьhashCode (), equals (), необязательный, но полезный toString (), а также, возможно, clone () и compareTo () для использования там, где они поддерживаются T и U - хотя требуется дополнительная работа для описания того, как эти контракты поддерживаютсяПарный класс.

5 голосов
/ 03 сентября 2013

Вот реализация из Android SDK

/**
 * 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.equal(p.first, first) && Objects.equal(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 голосов
/ 18 апреля 2013

Вы можете посмотреть на реализацию стандартных классов Java AbstractMap.SimpleEntry и AbstractMap.SimpleImmutableEntry . Гугл источники довольно легко:

3 голосов
/ 18 мая 2011

Думаю, нет. Цитата:

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

Я думаю, что они ожидают с точки зрения:

public class Pair<ThingA, ThingB>
2 голосов
/ 18 мая 2011

После редактирования все выглядит хорошо.

Однако вам действительно следует реализовать методы hashCode и equals, чтобы две пары, содержащие одинаковые объекты, были равны друг другу ииспользуется в качестве ключей в HashMap.И toString, если вы чувствуете себя щедрым.Эти методы не обязательны для выполнения заданных вами требований, но это то, что хороший программист добавил бы.

2 голосов
/ 18 мая 2011

Геттеры сломаны

public thing getFirst() {
  return thing.first;
}

public thing getSecond() {
  return thing.second;
}

thing следует заменить на this

2 голосов
/ 18 мая 2011

Обычно универсальный тип Pair имеет два параметра универсального типа, а не один - так что вы можете иметь (скажем) Pair<String, Integer>.Это, как правило, более полезно, IMO.

Я бы также предложил вам подумать о более обычном имени для вашего параметра типа, чем "вещь".Например, вы можете использовать Pair<A, B> или Pair<T, U>.

1 голос
/ 27 февраля 2018

Apache Commons Lang имеет реализацию общих пар

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html

1 голос
/ 18 мая 2011

Нет.Вы пробовали кодировать его, чтобы увидеть, работает ли он?

Вы, кажется, пропустили эту часть требования:

Параметризация класса должна выполняться по двум типам, один для первого членаи один для второго члена пары.

Это означает, что класс, вероятно, должен быть определен как нечто более похожее на:

public class Pair<T1, T2>

, а другойметоды обновляются соответственно.(Между прочим, я использовал T1 и T2 для ссылки на типы, так как условно используется короткий - 1 или 2 символьный идентификатор).

Также

return thing.first;

и

return thing.second;

не будут работать, как в вашем примере,thing это тип, а не объект.Подумайте о том, что вы хотите вернуть сюда.Вам даже нужно вызывать метод?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...