通过示例考虑以下简单的 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 是整数或 float 或其他一些数字类型。此外,默认情况下它返回一个整数列表,不过,通过将合适的函数作为可选的量化器参数传递,可以将此类型更改为其他类型。此外,如果数据参数是一个列表,则返回值将是一个列表;如果数据是一个元组,则返回值将是一个元组。 (这最后一个特性当然是最弱的一个,但它也是我最不想在 Java 中复制的一个特性,所以我没有费心让它变得更健壮。)
我想编写一个高效 Java 等效函数,这意味着弄清楚如何绕过 Java 的类型。自从我学习 Java(很久以前)以来,泛型就被引入了该语言。我尝试学习 Java 泛型,但发现它们非常难以理解。我不知道这是由于早发性衰老,还是因为自从我上次使用 Java 编程(大约 2001 年)以来 Java 的复杂性急剧增加,但我发现关于这个主题的每一页都比前一页更令人困惑一。如果有人能告诉我如何用 Java 执行此操作,我将不胜感激。
谢谢!
最佳答案
输入/输出类型问题的一个解决方案可能是使用 Number
类及其子类以及通配符。如果您想接受任何类型的数字参数,您可以将输入类型指定为 Number
或 ?扩展数字
。如果输入是一个列表,后一种形式有一个优势,因为它将确保列表中的每个元素都是相同的类型(必须是 Number 的子类)。 ?
被称为 Wildcard , 什么时候表示为 ? extends Number
它是一个“有界通配符”,并且只能引用边界类型的子类型。
例子:
public List<Number> func(List<? extends Number> data, Number nlevels)
这将采用 Number
的特定子类列表,nlevels 参数的 Number
,并返回 列表>数字
至于函数输入参数,可以输入一个Method
,尽管此时的类型检查变得困难,因为您会将一个有界未知参数的数据传递给一个方法
对象。我不确定这将如何工作。
至于返回类型,可以指定另一个参数,一个类对象(可能是 ? extends Number
再次),列表元素将被转换(或转换)到。
public List<? extends Number> quantize(List<? extends Number> data,
Number nlevels,
Method quantizer,
Class<? extends Number> returnType)
这是对您在 Java 中的函数的可能声明的尝试。然而,实现稍微复杂一些。
关于java - 如何将这种鸭子类型(duck typing)(Python)转换为 Java 泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6915265/