通过举例的方式考虑下面简单的Python功能:如何将这个duck-typing(Python)转换为Java泛型?
def quantize(data, nlevels, quantizer=lambda x, d: int(floor(x/d))):
llim = min(data)
delta = (max(data) - llim)/(nlevels - 1) # last level x == max(data) only
y = type(data)
if delta == 0:
return y([0] * len(data))
else:
return y([quantizer(x - llim, delta) for x in data])
这里,它是在行动:
>>> from random import random
>>> data = [10*random() for _ in range(10)]
>>> data
[6.6181668777075018, 9.0511321773967737, 1.8967672216187881, 7.3396890304913951,
4.0566699095012835, 2.3589022034131069, 0.76888247730320769, 8.994874996737197,
7.1717500363578246, 2.887112256757157]
>>> quantize(data, nlevels=5)
[2, 4, 0, 3, 1, 0, 0, 3, 3, 1]
>>> quantize(tuple(data), nlevels=5)
(2, 4, 0, 3, 1, 0, 0, 3, 3, 1)
>>> from math import floor
>>> quantize(data, nlevels=5, quantizer=lambda x, d: (floor(x/d) + 0.5))
[2.5, 4.5, 0.5, 3.5, 1.5, 0.5, 0.5, 3.5, 3.5, 1.5]
这个功能肯定有瑕疵──为一个东西,它不验证参数,它应该更聪明地设置返回值的类型 - 但它具有的优点是,无论数据中的元素是整数还是浮点数还是某种其他数值类型,它都可以工作。另外,默认情况下,它会返回一个整数列表,但是通过传递一个适当的函数作为可选的量化参数,可以将此类型更改为其他值。此外,如果数据参数是一个列表,返回的值将是一个列表;如果数据是一个元组,返回的值将是一个元组。 (这最后一个特性肯定是最弱的一个,但它也是我最不感兴趣的在Java中复制的,所以我没有费心使它更加健壮。)
我想写一个高效的这个函数与Java相当,这意味着要搞清楚如何避免Java的输入。自从我学习Java(以前)以来,泛型被引入到了语言中。我尝试了解Java泛型,但发现它们很难理解。我不知道这是由于早期衰老,还是由于自从我上次编程后(大约2001年)Java复杂性的巨大增长,但是我发现关于此主题的每一页都比以前更混乱一。我真的很感激,如果有人能告诉我如何在Java中做到这一点。
谢谢!
你想要它处理浮动/双打或整体? – jjnguy
那么鸭子式的功能既是缺点又是美德?你要么必须多次写这个方法,一次用于浮点数,一次用于整数等等,否则你将需要使整个类通用于T,并接受此方法中的List。 –
wberry