java - 如何将这种鸭子类型(duck typing)(Python)转换为 Java 泛型?

标签 java python generics types duck-typing

通过示例考虑以下简单的 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/

相关文章:

java - 我需要同步吗?

javascript - Django "static"文件 - Javascript

python - 如何对 Pandas 列中的唯一名称使用 groupby 和 cumcount

python - 为什么 numpy.ndarray.T 比 numpy.transpose(numpy.ndarray) 快得多?

Swift:泛型类中的声明

java - 将已知时区的日期转换为 UTC 日期

java - 如何从上一页检索信息?

java - 无法解析方法 openConnection()

java - 有界通配符相关的编译器错误

java - 如何在Eclipse中使用 "Infer Generic Type Arguments..."