programing tip

Java에는 한때 Pair 클래스가 없었습니까?

itbloger 2020. 8. 23. 08:38
반응형

Java에는 한때 Pair 클래스가 없었습니까? [복제]


이 질문에 이미 답변이 있습니다.

내가 잘못 기억하고 있습니까? 아니면 Java가 API의 일부로 Pair 클래스를 제공 했습니까?


표준 프레임 워크에는 Pair가 없지만 "standard"에 매우 가까운 Apache Commons Lang 에는 Pair가 있습니다.


Map.Entry

Java 1.6 이상 Map.Entry에는 키와 값을 페어링하는 두 가지 인터페이스 구현이 있습니다.

Map.Entry 인터페이스에서 상속 된 SimpleEntry 및 SimpleImmutableEntry 클래스의 UML 다이어그램

예를 들면

Map.Entry < Month, Boolean > pair = 
    new AbstractMap.SimpleImmutableEntry <>( 
        Month.AUGUST , 
        Boolean.TRUE 
    )
;

pair.toString () : AUGUST = true

쌍을 저장해야 할 때 사용합니다 (예 : 크기 및 개체 컬렉션).

내 프로덕션 코드에서이 부분 :

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)로 제한하고 유형 검사를 잃습니다.


페어 클래스 :

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;
    }

}

usage :

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

Immutable, only a pair !


There are lots of implementation around here, but all the time something is missing , the Override of equal and hash method.

here is a more complete version of this class:

/**
 * 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);
    }
}

This should help.

To sum it up: a generic Pair class doesn't have any special semantics and you could as well need a Tripplet class etc. The developers of Java thus didn't include a generic Pair but suggest to write special classes (which isn't that hard) like Point(x,y), Range(start, end) or Map.Entry(key, value).


No, but it's been requested many times.


Many 3rd party libraries have their versions of Pair, but Java has never had such a class. The closest is the inner interface java.util.Map.Entry, which exposes an immutable key property and a possibly mutable value property.


If you want a pair (not supposedly key-value pair) just to hold two generic data together neither of the solutions above really handy since first (or so called Key) cannot be changed (neither in Apache Commons Lang's Pair nor in AbstractMap.SimpleEntry). They have thier own reasons, but still you may need to be able to change both of the components. Here is a Pair class in which both elements can be set

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;
    }
}

It does seem odd. I found this thread, also thinking I'd seen one in the past, but couldn't find it in Javadoc.

I can see the Java developers' point about using specialised classes, and that the presence of a generic Pair class could cause developers to be lazy (perish the thought!)

However, in my experience, there are undoubtedly times when the thing you're modelling really is just a pair of things and coming up with a meaningful name for the relationship between the two halves of the pair, is actually more painful than just getting on with it. So instead, we're left to create a 'bespoke' class of practically boiler-plate code - probably called 'Pair'.

This could be a slippery slope, but a Pair and a Triplet class would cover a very large proportion of the use-cases.


No but JavaFX has it.

Cf. Stack Overflow: Java Pair class implementation

참고 URL : https://stackoverflow.com/questions/5303539/didnt-java-once-have-a-pair-class

반응형