通过示例考虑以下简单的Python函数:
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]
这个函数当然有缺陷 - 一方面,它不验证参数,它应该更聪明地设置返回值的类型 - 但它的优点是它将起作用是否元素in data是整数或浮点数或其他一些数字类型。此外,默认情况下,它返回一个int列表,但是,通过传递一个合适的函数作为可选的quantizer参数,此类型可以更改为其他类型。此外,如果data参数是一个列表,则返回的值将是一个列表;如果data是一个元组,返回的值将是一个元组。 (这最后一个功能肯定是最弱的一个,但它也是我最不感兴趣的用Java复制的功能,所以我不打算让它更强大。)
我想写一个高效的 Java等价的这个函数,这意味着要弄清楚如何绕过Java的输入。自从我学习Java(以前)以来,泛型被引入到该语言中。我已经尝试过了解Java泛型,但发现它们非常难以理解。我不知道这是由于早发性衰老,还是因为我上次编程后的Java复杂性的增长(大约2001年),但我在这个主题上找到的每一页都比以前更容易混淆一。如果有人能告诉我如何用Java做这件事,我真的很感激。
谢谢!
答案 0 :(得分:4)
输入/输出类型问题的一个解决方案可能是使用Number
类及其子类和通配符。如果要接受任何类型的数字参数,可以将输入类型指定为Number
或? extends Number
。如果输入是列表,则后一种形式具有优势,因为它将确保列表的每个元素具有相同的类型(必须是Number的子类)。 ?
被称为Wildcard,当它表示为? extends Number
时,它是“有界通配符”,并且可能只引用边界类型的子类型。
示例:
public List<Number> func(List<? extends Number> data, Number nlevels)
这将获取Number
的特定子类的列表,nlevels参数的Number
,并返回Number
的列表
对于函数输入参数,可以输入Method
,虽然此时的类型检查变得困难,因为您将有界未知参数的数据传递给{{1}对象。我不确定这是怎么回事。
对于返回类型,可以指定另一个参数,一个类对象(可能再次为Method
),列表元素将被转换(或转换)为。
? extends Number
这是尝试在Java中声明您的函数。然而,实施稍微复杂一些。
答案 1 :(得分:1)
这不是你问的问题,但我可以建议你试试Jython吗?您将能够获取Python代码并直接编译为Java字节码。由于您自2001年以来没有使用过Java,而且您最近似乎在使用Python,您可能会发现Jython更容易使用,而不是事先让自己快速掌握Java中的所有更改。