[英]Java: What is an alternative to using generics in this design?
我正在開發一個開放源Java庫,該庫將允許人們計算具有一定數量值的屬性的某些數量,例如Gini索引。 (從形式上講,它計算與屬性A
關聯的離散分布的基尼系數,但這與此處無關。)
例如,一個人將能夠執行以下操作
String[] namesArray = {"primary_school", "high_school", "university"};
Calculator<String> calc =new Calculator<String>(namesArray);
// p.getEducationLevel() returns `"primary_school"`, `"high_school"`, or `"university"`.
for (Person p : peopleCollection) {
calc.increment(p.getEducationLevel());
}
// e.g. the Gini index of the distribution
double currentStat = calc.getCurrentValue();
這個想法是允許庫的用戶使用他們自己的類型來引用屬性值。 在這種情況下,我正在使用字符串(例如"primary_school"
)。 但是我可能要使用整數,甚至是我自己的AttributeValue
類型。
我通過定義解決
public class Calculator<T> {
/* ... */
}
但是,使用泛型會在實現過程中引起一些問題:例如,如果我想維護類型對(T, double)
的集合,則必須進行討厭的類型轉換:
public class Calculator<T>
/* ... */
private Queue<StreamElement<T>> slidingWindow;
/* ... */
class StreamElement<T> {
private T label;
private double value;
StreamElement(T label, double value) {
this.label = label;
this.value = value;
}
public T getLabel() {
return label;
}
public double getValue() {
return value;
}
}
/* ... */
slidingWindow.add(new StreamElement<T>(label, value));
if (slidingWindow.size() > windowSize) {
StreamElement lastElement = slidingWindow.remove();
// XXX: Nasty type cast
decrement((T)lastElement.getLabel(), lastElement.getValue());
}
/* ... */
}
這是javac
產生的警告:
Calculator.java:163: warning: [unchecked] unchecked cast
decrement((T)lastElement.getLabel(), lastElement.getValue());
^
required: T
found: Object
where T is a type-variable:
T extends Object declared in class Calculator
1 warning
更新。 如果我不進行類型轉換,我會得到
Calculator.java:163: error: no suitable method found for decrement(Object,double)
decrement(lastElement.getLabel(), lastElement.getValue());
^
method Calculator.decrement(T) is not applicable
(actual and formal argument lists differ in length)
method Calculator.decrement(T,double) is not applicable
(actual argument Object cannot be converted to T by method invocation conversion)
where T is a type-variable:
T extends Object declared in class Calculator
1 error
問題:
MyLabel
然后使用MyLabel
作為屬性值的Label
類嗎? 這意味着Calculator
將不再是通用類型; 在實現中,我們將使用class StreamElement { Label label; /* ... */ }
class StreamElement { Label label; /* ... */ }
等。 我認為您剛剛犯了一些錯誤。
這是正確的實現:
/* ... */
slidingWindow.add(new StreamElement<T>(label, value));
if (slidingWindow.size() > windowSize) {
// Don't forget the generic argument at StreamElement
StreamElement<T> lastElement = slidingWindow.remove();
decrement(lastElement.getLabel(), lastElement.getValue());
}
/* ... */
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.