Java 泛型和 Infinity(可比较)
使用 Integer 类型,您可以执行以下操作:
int lowest = Integer.MIN_VALUE;
如果我使用泛型,我可以做什么?
K lowest = <...>;
我需要这个来实现类似于 PriorityQueue 的东西。 我可以访问要从队列中删除的节点,但它不是最小值。
1. I need to make it the min by decreasing the key of that node,
2. And then remove the min.
我被困在第一步了。 我唯一能做的就是将节点的密钥设置为当前最小值。 不确定这是否足够。
With the type Integer you can do this:
int lowest = Integer.MIN_VALUE;
What can I do if I use generics?
K lowest = <...>;
I need this in order to implement something similar to a PriorityQueue.
I have access to a node I want to remove from the queue, but it is not the min.
1. I need to make it the min by decreasing the key of that node,
2. And then remove the min.
I am stuck on the first step. The only thing I can do is set the key of the node to the current min. Not sure it is enough.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
考虑不要使
K
成为泛型,而是使用包装原始包装器的接口(双重包装器!)。简而言之,这个想法是,每当实例化一个新类时,都会创建一个最小值并将其放入存储每个类的最小值的静态哈希图中。 (事实上,这些值根本就不是什么,只是一个哨兵对象,但是由于我们将使用对象相等性来确定某个值是否为最小值,所以这根本没有问题。)所需要的只是包装的对象具有可比性一般而言,对于其自身的其他实例。
一个缺点是,当您调用
getMinValue
时,您将收到编译器警告,因为返回类型没有通用信息。 可能有一种更优雅的方法来解决这个问题,但我现在想不到。总体而言,这个总体想法可能相当不错。 然而,我真的应该强调:如果您尝试使用任何多态性或任何相互可比较的类的混合,这绝对会失败。 同一棵树中的
Long
和Integer
将彻底摧毁你。Consider not making
K
a generic, but using an interface that wraps the primitive wrapper (a double wrapper!).Briefly, the idea is that whenever a new class is instantiated, a minimum value is created and put into a static hashmap that stores the minimum values for each class. (In fact, these values are NOTHING at all, just a sentinel object, but since we will use object equality to determine if something is the min value, this is no problem at all.) All that's necessary is that the wrapped object be comparable to other instances of itself in general.
One drawback is that when you call
getMinValue
you will have compiler warnings, since the return type will have no generic information. There may be a more elegant way around this, but I can't think of it right now.This general idea might be rather nice overall. However, I should really stress: this will absolutely break if you try it with any polymorphism or any mixing of mutually comparable classes.
Long
s andInteger
s in the same tree will completely destroy you.呃……又出什么问题了?
PriorityQueue,像所有集合,允许您使用对象的实例 将其从集合中删除。
er... what's the problem again?
PriorityQueue, like all Collections, allows you to use an instance of an object to remove it from the collection.
呃,这不是取决于K是什么类型吗?
泛型的要点是 K 可以是任何类型(或某种类型的任何子类); 为了能够调用 K 上的方法或访问它的属性,您需要使用通配符限制它的类型界限。
Uh doesn't this depend on what type K is?
The point of Generics is that K can be any type (or any subclass of a certain type); in order to be able to call methods on K or access properties of it, you need to restrict it's type bounds with wildcards.
仅仅因为一个对象是可比较的并不意味着它必须具有最小值。 int 的最小值为 -(2^(31)) 的原因是因为符号需要 1 位,因此 2^31 是可以存储的最大(或最小)整数。 对于像字符串这样的东西,它没有任何意义,因为没有最大/最小可能的字符串,它是内存限制的。
just because an object is a comparable does not mean it has to have a minimum value. The reason int has a min value of -(2^(31)) is because you need 1 bit for a sign, so 2^31 is the largest (or smallest) possible integer that can be stored. For things like string, it does not make any sense since there is no largest/smallest possible string, it is memory bound.
您可能必须创建一个接口“IInfinity”,并让 K 扩展 IInfinity,让 IInfinity 具有方法“getInfinityValue()”,然后在实现 IInfinity 的类中包装/扩展 Integer、Double、BigDecimal 等...呃!
You might have to create an interface "IInfinity", and have K extends IInfinity, and IInfinity to have a method "getInfinityValue()", and then wrap/extend Integer, Double, BigDecimal, etc in a class that implements IInfinity ... and ugh!
基本上,您希望任何类型 K 实现一些静态函数,例如遵守标准数学属性的最低和最高函数。
我假设为了使这种最低(或最高)的感觉可用,您会希望任何 Comparable 对象都具有这些方法。 (或静态字段)。 如果您只对自己的自定义对象感兴趣,则执行此操作的方法是让所有内容都继承自抽象数据类型,该抽象数据类型声明了 MINVALUE 和 MAX_VALUE 的静态字段,然后您的类型变量将为 . 如果其他类需要此功能,则需要创建某种外部哈希图来跟踪不同类的这些属性(但这会变得非常难看)
Basically you want any type K to implement some static functions say lowest and highest which obey the standard mathematical properties.
I assume that for this sense of lowest (or highest) to be usable you would want any Comparable object to have these methods. (or static fields). If you are only interested in your own custom objects, the way to do this would be to have everything inherit from an abstract data type which declared static fields for MINVALUE and MAX_VALUE and then your type varaibles would be . If you need this functionality for other classes you will need to cre4ate some sort of external hashmap which tracks these properties for different classes (but that would get pretty ugly)
对于所有 Comparable 类型,没有通用形式的
MIN_VALUE
或MAX_VALUE
。考虑一个实现可比较的
Time
类。 尽管 Time 是 Comparable,但它没有MAX_VALUE
。There is no generic form of
MIN_VALUE
orMAX_VALUE
for all Comparable types.Think about a
Time
class that implements comparable. There is noMAX_VALUE
for Time even though it is Comparable.我试图想象什么情况下需要这样的行为。 这是我能想到的最好的...
警告:此代码很危险。 请怜悯我发布如此令人厌恶的内容。 这只是一个概念证明。
进而...
I am trying to imagine what scenario would require such behavior. This is the best I can come up with...
WARNING: This code is dangerous. Please be merciful to me for posting such an abomination. It is only a proof of concept.
And then...
这没有任何意义...
鉴于您当时不知道 K 是什么,(即您一般地实现它...废话!)您无法为其指定最小/最大界限。
在 K 可能是 int、long、string OR 对象的情况下,您无法明智地猜测使用
Integer.MIN_VALUE、"" OR NULL。
我猜您正在寻找的是 K.MIN_VALUE_OF_EVENTUAL_TYPE 但它不存在。
This doesn't make any sense...
Given that you don't know what K is at that point, (i.e. You're implementing it generically... duh!) you can't specify a min/max bound for it.
in a case where K could be a int, long, string OR object, you couldn't sensibly guess to use
Integer.MIN_VALUE, "" OR NULL.
I guess what you're looking for is a K.MIN_VALUE_OF_EVENTUAL_TYPE but that doesn't exist.
您可以创建一个包装类,为所有类型“添加”最小值和最大值。 它只有两个代表最小值和最大值的静态实例,然后其他实例包装某种类型的其他值。 当我们进行比较时,我们检查其中一项是否是最小值或最大值,并返回正确的结果; 否则我们只进行与基础类型相同的比较。 像这样的事情:
You can make a wrapper class that "adds" a minimum and maximum value to all types. It just has two static instances that represent minimum and maximum, and then other instances wrap some other value of some type. When we do a comparison, we check if one of the things is the minimum or maximum, and return the proper result; and otherwise we just do the same comparison as the underlying type. Something like this: