3

以下面的简单 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]

这个函数当然有缺陷——一方面,它不验证参数,而且它应该更聪明地设置返回值的类型——但它的优点是无论数据中的元素是整数或浮点数或其他一些数字类型。此外,默认情况下,它返回一个整数列表,但是,通过传递一个合适的函数作为可选的量化器参数,这种类型可以更改为其他类型。此外,如果 data 参数是一个列表,则返回值将是一个列表;如果 data 是一个元组,则返回值将是一个元组。(最后一个特性肯定是最弱的,但它也是我对在 Java 中复制最不感兴趣的特性,所以我没有费心让它变得更健壮。)

我想为这个函数编写一个有效的Java 等效函数,这意味着要弄清楚如何绕过 Java 的打字。自从我学习 Java(很久以前)以来,泛型就被引入了该语言。我尝试过学习 Java 泛型,但发现它们非常难以理解。我不知道这是由于早发性衰老,还是因为自从我上次在 Java 中编程(约 2001 年)以来,Java 的复杂性急剧增加,但我发现的关于这个主题的每一页都比上一页更令人困惑一。如果有人能告诉我如何用 Java 做到这一点,我将不胜感激。

谢谢!

4

2 回答 2

4

输入/输出类型问题的一种解决方案可能是使用Number类及其子类以及通配符。如果您想接受任何类型的数值参数,您可以将输入类型指定为NumberOR ? extends Number。如果输入是一个列表,后一种形式有一个优势,因为它可以确保列表的每个元素都是相同的类型(必须是 Number 的子类)。被?称为通配符,当它表示为? extends Number“有界通配符”时,可能仅指有界类型的子类型。

例子:

public List<Number> func(List<? extends Number> data, Number nlevels)

这将采用 的特定子类的列表Number,aNumber用于 nlevels 参数,并返回Numbers的列表

至于函数输入参数,可以输入 a Method,尽管此时类型检查变得困难,因为您会将有界未知参数的数据传递给Method对象。我不确定这将如何工作。

至于返回类型,可以指定另一个参数,? extends Number即列表元素将被强制转换(或转换)为的类对象(可能又是一个)。

public List<? extends Number> quantize(List<? extends Number> data, 
                                       Number nlevels, 
                                       Method quantizer, 
                                       Class<? extends Number> returnType)

这是在 Java 中为您的函数声明可能的尝试。然而,实现有点复杂。

于 2011-08-02T16:43:12.887 回答
1

这不是您所问的,但我可以建议尝试一下Jython吗?您将能够获取您的 Python 代码并直接编译为 Java 字节码。由于您自 2001 年以来就没有使用过 Java,而且这些天您似乎在使用 Python,因此您可能会发现使用 Jython 比让自己提前了解 Java 中的所有变化要容易得多。

于 2011-08-02T16:25:26.643 回答