Рассмотрим в качестве примера следующую простую функцию 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 - кортеж, возвращаемое значение будет кортежем. (Эта последняя функция, безусловно, самая слабая, но она также меньше всего интересует меня для репликации в Java, поэтому я не стал делать ее более надежной.)
Я хотел бы написать эффективный Java-эквивалент этой функции, что означает выяснение того, как обойти типизацию Java. Так как я изучал Java (эоны назад), в язык были введены дженерики. Я пытался узнать о дженериках Java, но нашел их довольно непонятными. Я не знаю, связано ли это с ранним маразмом или с явным ростом сложности Java с тех пор, как я в последний раз программировал его (около 2001 г.), но каждая страница, которую я нахожу по этой теме, более запутанна, чем предыдущая один. Я был бы очень признателен, если бы кто-нибудь показал мне, как это сделать на Java.
Спасибо!