Java中没有Pair<L,R>,有什么好理由吗?与这个c++构造等价的是什么?我宁愿避免重新实现我自己的。
似乎1.6提供了类似的东西(AbstractMap.SimpleEntry<K,V>),但这看起来相当复杂。
Java中没有Pair<L,R>,有什么好理由吗?与这个c++构造等价的是什么?我宁愿避免重新实现我自己的。
似乎1.6提供了类似的东西(AbstractMap.SimpleEntry<K,V>),但这看起来相当复杂。
当前回答
尽管语法相似,但Java和c++有非常不同的范例。像Java一样写c++是糟糕的c++,像c++一样写Java是糟糕的Java。
使用像Eclipse这样基于反射的IDE,编写“pair”类的必要功能是快速而简单的。创建类,定义两个字段,使用各种“Generate XX”菜单选项在几秒钟内填写类。如果你想要Comparable界面,也许你必须很快地输入一个“compareTo”。
由于c++语言中有单独的声明/定义选项,代码生成器并不是很好,所以手工编写小的实用程序类更加费时乏味。由于pair是一个模板,您不必为不使用的函数付费,并且typedef功能允许为代码分配有意义的类型名,因此关于“无语义”的反对意见并不成立。
其他回答
地图。入口界面非常接近c++对。看看具体的实现,比如AbstractMap。SimpleEntry和AbstractMap。SimpleImmutableEntry 第一项是getKey(),第二项是getValue()。
在我看来,Java中没有Pair,因为如果你想直接在Pair上添加额外的功能(例如Comparable),你必须绑定类型。在c++中,我们不在乎,如果组成一个pair的类型没有操作符<,则pair::operator <也不会被编译。
Comparable的一个例子:
public class Pair<F, S> implements Comparable<Pair<? extends F, ? extends S>> {
public final F first;
public final S second;
/* ... */
public int compareTo(Pair<? extends F, ? extends S> that) {
int cf = compare(first, that.first);
return cf == 0 ? compare(second, that.second) : cf;
}
//Why null is decided to be less than everything?
private static int compare(Object l, Object r) {
if (l == null) {
return r == null ? 0 : -1;
} else {
return r == null ? 1 : ((Comparable) (l)).compareTo(r);
}
}
}
/* ... */
Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
//Runtime error here instead of compile error!
System.out.println(a.compareTo(b));
Comparable与编译时检查类型参数是否可比较的示例:
public class Pair<
F extends Comparable<? super F>,
S extends Comparable<? super S>
> implements Comparable<Pair<? extends F, ? extends S>> {
public final F first;
public final S second;
/* ... */
public int compareTo(Pair<? extends F, ? extends S> that) {
int cf = compare(first, that.first);
return cf == 0 ? compare(second, that.second) : cf;
}
//Why null is decided to be less than everything?
private static <
T extends Comparable<? super T>
> int compare(T l, T r) {
if (l == null) {
return r == null ? 0 : -1;
} else {
return r == null ? 1 : l.compareTo(r);
}
}
}
/* ... */
//Will not compile because Thread is not Comparable<? super Thread>
Pair<Thread, HashMap<String, Integer>> a = /* ... */;
Pair<Thread, HashMap<String, Integer>> b = /* ... */;
System.out.println(a.compareTo(b));
这很好,但是这次您不能在Pair中使用不可比较的类型作为类型参数。 你可能会在一些实用程序类中使用很多comparator for Pair,但是c++的人可能不会理解。另一种方法是在类型层次结构中编写很多类,在类型参数上有不同的边界,但是有太多可能的边界和它们的组合……
http://www.javatuples.org/index.html怎么样?我发现它非常有用。
javatuples提供了从一到十个元素的元组类:
Unit<A> (1 element)
Pair<A,B> (2 elements)
Triplet<A,B,C> (3 elements)
Quartet<A,B,C,D> (4 elements)
Quintet<A,B,C,D,E> (5 elements)
Sextet<A,B,C,D,E,F> (6 elements)
Septet<A,B,C,D,E,F,G> (7 elements)
Octet<A,B,C,D,E,F,G,H> (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> (10 elements)
@Andreas Krey的回答其实很好。任何Java给你带来困难的事情,你都不应该去做。
在我的经验中,Pair最常见的用途是一个方法的多个返回值和hashmap中的values(通常由字符串索引)。
在后一种情况下,我最近使用了一个数据结构,类似这样:
class SumHolder{MyObject trackedObject, double sum};
这是您的整个“Pair”类,与通用的“Pair”类的代码数量几乎相同,但具有描述性名称的优势。它可以在它使用的方法中定义,这将消除公共变量等典型问题。换句话说,对于这种用法,它绝对比一对更好(由于命名的成员),不会更差。
If you actually want a "Pair" for the key of a hashmap you are essentially creating a double-key index. I think this may be the one case where a "Pair" is significantly less code. It's not really easier because you could have eclipse generate equals/hash on your little data class, but it would be a good deal more code. Here a Pair would be a quick fix, but if you need a double-indexed hash who's to say you don't need an n-indexed hash? The data class solution will scale up, the Pair will not unless you nest them!
So the second case, returning from a method, is a bit harder. Your class needs more visibility (the caller needs to see it too). You can define it outside the method but inside the class exactly as above. At that point your method should be able to return a MyClass.SumHolder object. The caller gets to see the names of the returned objects, not just a "Pair". Note again that the "Default" security of package level is pretty good--it's restrictive enough that you shouldn't get yourself into too much trouble. Better than a "Pair" object anyway.
我能看到的另一种情况是使用一个公共api,为当前包之外的调用者提供返回值。为此,我只创建一个真正的对象——最好是不可变的。最终,调用者将共享此返回值,并且使其可变可能会出现问题。这是Pair对象更糟糕的另一种情况——大多数Pair不能被设置为不可变的。
所有这些情况的另一个优点是——java类扩展,我的sum类需要第二个sum和“Created”标记,当我完成时,我将不得不扔掉Pair并使用其他东西,但如果Pair有意义,我的4个值的类至少仍然有意义。
试试VAVR元组。
vavr不仅有一组很好的元组类型,而且对函数式编程也有很好的支持。