没有';Java有一个Pair类吗?

没有';Java有一个Pair类吗?,java,Java,是我记错了,还是Java曾经提供了一个Pair类作为其API的一部分?应该会有所帮助 总而言之:一个泛型对类没有任何特殊的语义,你也可以需要一个Tripplet类等。因此,Java开发人员没有包含泛型对但建议编写特殊类(这并不难),比如点(x,y),范围(开始,结束)或Map.Entry(key,value)没有,但已经有了。许多第三方库都有自己的Pair版本,但Java从未有过这样的类。最接近的是内部接口java.util.Map.Entry,它公开了一个不可变的键属性和一个可能可变的值属性。

是我记错了,还是Java曾经提供了一个Pair类作为其API的一部分?

应该会有所帮助


总而言之:一个泛型
类没有任何特殊的语义,你也可以需要一个
Tripplet
类等。因此,Java开发人员没有包含泛型
但建议编写特殊类(这并不难),比如
点(x,y)
范围(开始,结束)
Map.Entry(key,value)

没有,但已经有了。

许多第三方库都有自己的Pair版本,但Java从未有过这样的类。最接近的是内部接口java.util.Map.Entry,它公开了一个不可变的键属性和一个可能可变的值属性。

标准框架中没有对,但是非常接近“标准”的有一个对类。

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

}
公共类对{
私有最终K元素0;
私人最后五项要素1;
公共静态对createPair(K元素0,V元素1){
返回新的一对(element0,element1);
}
公共对(K元素0,V元素1){
this.element0=element0;
this.element1=element1;
}
公共K getElement0(){
返回元素0;
}
public V getElement1(){
返回元素1;
}
}
用法:

Pair<Integer, String> pair = Pair.createPair(1, "test");
pair.getElement0();
pair.getElement1();
Pair-Pair=Pair.createPair(1,“测试”);
pair.getElement0();
pair.getElement1();

不变,只有一对

这看起来确实很奇怪。我发现了这个线程,还以为我以前见过一个,但在Javadoc中找不到

我可以理解Java开发人员关于使用专门类的观点,并且泛型Pair类的存在可能会导致开发人员懒惰(放弃这种想法!)

然而,根据我的经验,毫无疑问,有时你正在建模的东西实际上只是一对东西,为这对东西的两半之间的关系想出一个有意义的名字,实际上比继续下去更痛苦。因此,我们需要创建一个“定制”类,该类实际上是锅炉板代码——可能称为“Pair”

这可能是一个滑铁卢,但一对和一个三元组类将覆盖很大一部分用例。

Map.Entry
Java 1.6和更高版本有两种接口实现,将键与值配对:

比如说

Map.Entry < Month, Boolean > pair = 
    new AbstractMap.SimpleImmutableEntry <>( 
        Month.AUGUST , 
        Boolean.TRUE 
    )
;
Map.Entrypair=
新建AbstractMap.SimpleImmutableEntry(
八月,
布尔。真
)
;
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));
}
公共地图
getEventTable(风险分类器){
Map l1s=新的HashMap();
Map l2s=新的HashMap();
Map l3s=新的HashMap();
列表事件=新建ArrayList();
...
地图放置(l3s,事件);
put(l2s,新的AbstractMap.SimpleImmutableEntry(l3Size,l3s));
put(l1s,新的AbstractMap.SimpleImmutableEntry(l2Size,l2s));
}

代码看起来很复杂,但不是映射。条目您仅限于对象数组(大小为2)和丢失类型检查…

这里有很多实现,但始终缺少一些内容,即对equal和hash方法的重写

下面是该类的更完整版本:

/**
 * 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);
    }
}
/**
*容器,以方便传递两个对象的元组。该对象提供了一个合理的
*equals()的实现,如果包含的每个
*对象。
*/
公共类对{
公开决赛F-first;
公开决赛第二名;
/**
*一对的构造函数。
*
*@param first该对中的第一个对象
*@param second该对中的第二个对象
*/
公共对(F第一,S第二){
this.first=first;
这个秒=秒;
}
/**
*通过委托给两个对象各自的代理来检查这两个对象是否相等
*{@link Object#equals(Object)}方法。
*
*@param o要检查其相等性的{@link Pair}
*@如果该对的基础对象都被考虑,则返回true
*相等的
*/
@凌驾
公共布尔等于(对象o){
如果(!(对的o实例)){
返回false;
}
对p=(对)o;
返回Objects.equals(p.first,first)和&Objects.equals(p.second,second);
}
/**
*使用底层对象的哈希代码计算哈希代码
*
*@返回该对的哈希代码
*/
@凌驾
公共int hashCode(){
返回(first==null?0:first.hashCode())^(second==null?0:second.hashCode());
}
/**
*创建适当类型对的简便方法。
*@param a是该对中的第一个对象
*@param b该对中的第二个对象
*@返回一个模板化为a和b类型的对
*/
公共静态对创建(A、B){
返回新的一对(a,b);
}
}
如果您想要一对(不是所谓的键值对)来将两个通用数据保存在一起,那么上面的解决方案都不是很方便,因为第一个(或所谓的键)不能更改(既不能在Apache Commons Lang的对中,也不能在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;
    }
}
公共类对{
私人优先;
私人第二;
公共对(第一对、第二对){
this.first=first;
这个秒=秒;
}
公共无效设置优先(优先){
this.first=first;
}
公共无效设置秒(秒){
这个秒=秒;
}
冷杉