【问题标题】:List of Generics泛型列表
【发布时间】:2015-09-11 21:45:46
【问题描述】:

所以我有一个简单的 Java 类 DatedValue 如下:

public class DatedValue<V> implements Comparable<DatedValue>{

private V value;
private Date date;

public DatedValue(V value, Date date){
    this.value = value;
    this.date = date;
}

public V getValue(){
    return value;
}

public Date getDate(){
    return date;
}

@Override
public int compareTo(DatedValue dv) {
    return date.compareTo(dv.date);
}

}

而且我有一个这个类的对象列表,如下:

List<DatedValue<Float>> list =  new ArrayList<DatedValue<Float>>();

我可以用 DatedValue 填充这个列表。

但是,当我尝试使用此列表中 DatedValue 的 getValue 函数时,它返回一个 Object 而不是 Float。我终其一生都无法弄清楚为什么。

感谢任何帮助!

编辑:

这是整个上下文。这可能会很混乱。

public class MomentumFormula {

private List<DatedValue<Float>> pricedata;
private List<Integer> upmomentumdata;
private List<Integer> downmomentumdata;

public MomentumFormula(String stock, GregorianCalendar startdate,
        GregorianCalendar enddate){
    pricedata = new ArrayList<>();
    upmomentumdata = new ArrayList<>();
    downmomentumdata = new ArrayList<>();
    DBManager db = new DBManager("stockdata");
    try{
        Connection dbconn = db.getConnection();
        Statement stmt = dbconn.createStatement();
        String tablename = stock;
        if(tablename.contains(".")){
            tablename = new StringBuilder("stock").
                    append(tablename.replace(".", "period")).toString();
        }else{
            tablename = new StringBuilder("stock").
                    append(tablename).toString();
        }
        ResultSet rs = stmt.executeQuery(new StringBuilder(
                "SELECT * FROM ").append(tablename).
                append(" WHERE date BETWEEN STR_TO_DATE('").
                append((startdate.get(Calendar.MONTH) + 1)).append(", ").
                append(startdate.get(Calendar.DATE)).append(", ").
                append(startdate.get(Calendar.YEAR)).
                append("', '%m, %d, %Y')").append(" AND ").
                append("STR_TO_DATE('").
                append((enddate.get(Calendar.MONTH) + 1)).append(", ").
                append(enddate.get(Calendar.DATE)).append(", ").
                append(enddate.get(Calendar.YEAR)).
                append("', '%m, %d, %Y')").
                toString());
        while(rs.next()){                
            pricedata.add(new DatedValue<>(rs.getFloat("close"),
                    rs.getDate("date")));
        }
        Collections.sort(pricedata);
        if(pricedata.size() != 0){
            DatedValue<Float> first = pricedata.get(0);
            DatedValue<Float> highesthigh = new DatedValue<>(
                    first.getValue(), first.getDate());
            DatedValue<Float> lowestlow = new DatedValue<>(
                    first.getValue(), first.getDate());
            if(highesthigh.getValue() > lowestlow.getValue()){}
            for(DatedValue v : pricedata){
                if(v.getValue() > highesthigh.getValue()){
                    highesthigh = v;
                }
            }
        }
    }catch(Exception e){
        System.out.println("Exception in MomentumFormula");
        System.out.println(e.toString());
    }
}

}

错误发生就行了:

if(v.getValue() > highesthigh.getValue()){

Exception in MomentumFormula
java.lang.RuntimeException: Uncompilable source code - bad operand types for binary operator '>'
  first type:  java.lang.Object
  second type: java.lang.Float

【问题讨论】:

  • 向我们展示您的调用站点和编译器错误。
  • 很可能您在未显示的代码中某处使用了原始DatedValue。请说明您如何从列表中访问您的DatedValue
  • 当您从列表中获取 DatedValue 时,不要忘记将其泛型类型也设置为 Float。
  • 这就是问题所在!我将 for(DatedValue : pricedata) 更改为 for(DatedValue v : pricedata) 并且它起作用了。我想我只是假设 Java 会自动引用这些信息。

标签: java list generics


【解决方案1】:

您在那里使用“原始”DatedValue。这意味着编译器不知道getValue() 的结果的特定类型,并将其视为Object。因为关系运算符&gt; 只为数字操作数定义,所以应该会出现编译错误。

要修复它,请为您的DatedValue 指定一个类型参数。事实上,修复所有出现警告的情况:“DatedValue 是原始类型。对泛型类型 DatedValue 的引用应该被参数化。”

引起问题的for-loop 应该包含一个类型参数:

for(DatedValue<Float> v : pricedata){
  if(v.getValue() > highesthigh.getValue()){
    highesthigh = v;
  }
}

DateValue 类还有许多其他问题。

implements 子句应为implements Comparable&lt;DatedValue&lt;V&gt;&gt;compareTo() 方法应声明为public int compareTo(DatedValue&lt;V&gt; dv)。这将消除原始类型警告。

如果您实现Comparable,您还应该覆盖equals()hashCode(),以便它们产生一致的结果。这意味着您的 compareTo() 方法应该回退到在日期相同时比较 value

此外,您可以直接访问字段,而不是使用您定义的访问器方法。您应该将DateValue 声明为final,这样这些访问器就不会被覆盖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多