Java泛型和无穷大(可比)
使用Integer类型,可以执行以下操作:Java泛型和无穷大(可比),java,generics,comparable,infinity,Java,Generics,Comparable,Infinity,使用Integer类型,可以执行以下操作: int lowest = Integer.MIN_VALUE; 如果我使用泛型,我能做什么 K lowest = <...>; 我被困在第一步。我唯一能做的就是将节点的键设置为当前的最小值。我不确定这是否足够。嗯,这不取决于K是什么类型吗 泛型的要点是K可以是任何类型(或某一类型的任何子类);为了能够调用K上的方法或访问它的属性,您需要使用通配符限制它的类型边界。这没有任何意义 考虑到此时您不知道K是什么(即,您一般地实现它…duh!)
int lowest = Integer.MIN_VALUE;
如果我使用泛型,我能做什么
K lowest = <...>;
我被困在第一步。我唯一能做的就是将节点的键设置为当前的最小值。我不确定这是否足够。嗯,这不取决于K是什么类型吗
泛型的要点是K可以是任何类型(或某一类型的任何子类);为了能够调用K上的方法或访问它的属性,您需要使用通配符限制它的类型边界。这没有任何意义 考虑到此时您不知道K是什么(即,您一般地实现它…duh!),您不能为它指定最小/最大界限 在K可能是int、long、string或object的情况下,您无法明智地猜测使用 Integer.MIN_值“”或NULL
我想你要找的是一个K.MIN_值,它是最终的类型,但并不存在。对于所有可比较的类型,都没有
MIN_值
或MAX_值
的通用形式
考虑一个实现comparable的
Time
类。时间没有最大值,即使它是可比较的。仅仅因为对象是可比较的,并不意味着它必须有最小值。int的最小值为-(2^(31))的原因是符号需要1位,因此2^31是可以存储的最大(或最小)整数。对于像字符串这样的东西,它没有任何意义,因为没有可能的最大/最小字符串,它是内存限制的。您可能必须创建一个接口“IInfinity”,并让K扩展IInfinity,IInfinity有一个方法“getInfinityValue()”,然后包装/扩展Integer、Double、BigDecimal,在实现IInfinity的类中。。。啊 基本上,您希望任何类型的K都实现一些静态函数,比如最低和最高函数,它们遵循标准的数学属性
我假设,为了使这种最低(或最高)的感觉可用,您希望任何可比较的对象都有这些方法。(或静态字段)。如果您只对自己的自定义对象感兴趣,那么实现这一点的方法是让所有内容都从抽象数据类型继承,该抽象数据类型为MINVALUE和MAX_VALUE声明静态字段,然后您的类型变量将是。如果其他类需要此功能,则需要创建某种外部hashmap,用于跟踪不同类的这些属性(但这会变得非常难看)我正在尝试想象什么场景需要此类行为。这是我能想到的最好的 警告:此代码很危险。请原谅我张贴了这样一个令人憎恶的帖子。这只是一个概念的证明
public class Lowest<K> implements Comparable<K> {
public int compareTo(K other) {
return -1;
}
}
公共类{
公共整数比较(K其他){
返回-1;
}
}
然后
public class Test {
public <K extends Comparable<K>> K findMaximum(List<K> values) throws Exception {
K lowest = (K) new Lowest<K>(); /// XXX DANGER! Losing compile-time safety!!!
K maximum = lowest;
for (K value : values) {
if (maximum.compareTo(value) < 0) {
maximum = value;
}
}
if (maximum == lowest) {
throw new Exception("Could not find a maximum value");
} else {
return maximum;
}
}
}
公共类测试{
公共K findMaximum(列表值)引发异常{
K loost=(K)new loost();///XXX危险!正在失去编译时安全性!!!
K最大值=最低值;
对于(K值:值){
if(最大比较值)<0){
最大值=最大值;
}
}
如果(最大值==最低值){
抛出新异常(“找不到最大值”);
}否则{
返回最大值;
}
}
}
考虑不要使K
成为泛型,而是使用一个包装基本包装器(双包装器!)的接口
import java.util.HashMap;
公共类NodeWrapper实现了可比较的{
private static HashMap minVals=new HashMap();
私人K值;
私有节点包装器(){
超级();
}
公共节点包装器(K值,类clazz){
超级();
这个值=值;
if(minVals.get(clazz)==null){
minVals.put(clazz,newnodewrapper());
}
}
公共K getValue(){
返回值;
}
公共静态节点包装器getMinValue(类clazz){
返回minVals.get(clazz);
}
公共无效设置值(K值){
这个值=值;
}
@凌驾
公共整数比较(nodeo){
NodeWrapper min=minVals.get(this.getClass());
if(this==min&&o==min){
返回0;
}else if(this==min){
返回-1;
}如果(o==最小值),则为else{
返回1;
}否则{
返回此.value.compareTo(o.value);
}
}
}
简单地说,其思想是每当实例化一个新类时,都会创建一个最小值并将其放入一个静态hashmap中,该静态hashmap存储每个类的最小值。(事实上,这些值根本不是什么,只是一个sentinel对象,但由于我们将使用对象相等性来确定某个值是否为最小值,这一点都没有问题。)所需要的是,包装对象通常与自身的其他实例相比较
一个缺点是调用getMinValue
时会出现编译器警告,因为返回类型没有通用信息。也许有一种更优雅的方式,但我现在想不起来
总的来说,这个总体想法可能相当不错。然而,我要强调的是:如果你尝试任何多态性或任何相互比较的类的混合,这将是绝对失败的<同一棵树中的code>Longs和
Integer
s将彻底摧毁您。er。。。又是什么问题
与all一样,允许您使用集合中对象的实例来创建它。您可以创建一个包装类,为所有类型“添加”最小值和最大值。它只有两个表示最小值和最大值的静态实例,然后其他实例包装某种类型的其他值。当我们进行比较时,我们检查其中一项是最小值还是最大值,并返回正确的结果;和
public class Test {
public <K extends Comparable<K>> K findMaximum(List<K> values) throws Exception {
K lowest = (K) new Lowest<K>(); /// XXX DANGER! Losing compile-time safety!!!
K maximum = lowest;
for (K value : values) {
if (maximum.compareTo(value) < 0) {
maximum = value;
}
}
if (maximum == lowest) {
throw new Exception("Could not find a maximum value");
} else {
return maximum;
}
}
}
import java.util.HashMap;
public class NodeWrapper<K extends Comparable<K>> implements Comparable<NodeWrapper<K>> {
private static HashMap<Class, NodeWrapper> minVals = new HashMap<Class, NodeWrapper>();
private K value;
private NodeWrapper() {
super();
}
public NodeWrapper(K value, Class<K> clazz) {
super();
this.value = value;
if (minVals.get(clazz)==null) {
minVals.put(clazz, new NodeWrapper<K>());
}
}
public K getValue() {
return value;
}
public static NodeWrapper getMinValue(Class clazz){
return minVals.get(clazz);
}
public void setValue(K value) {
this.value = value;
}
@Override
public int compareTo(NodeWrapper<K> o) {
NodeWrapper min = minVals.get(this.getClass());
if (this==min && o==min) {
return 0;
} else if (this==min){
return -1;
} else if (o==min){
return 1;
} else {
return this.value.compareTo(o.value);
}
}
}
class Extended<T extends Comparable<? super T>> implements Comparable<Extended<T>> {
private Extended() { }
private static Extended min = new Extended();
private static Extended max = new Extended();
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> Extended<T> getMin() {
return (Extended<T>)min;
}
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> Extended<T> getMax() {
return (Extended<T>)max;
}
public T value;
public Extended(T x) { value = x; }
public int compareTo(Extended<T> other) {
if (this == other) return 0;
else if (this == min || other == max) return -1;
else if (this == max || other == min) return 1;
else return this.value.compareTo(other.value);
}
}