0

So I have a simple Java class DatedValue as follows:

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);
}

}

And I have a list of objects of this class, as follows:

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

And I can populate this list with DatedValue<Floats>.

However, when I try to use the getValue function of a DatedValue from this list, it returns an Object rather than a Float. I cannot for the life of me figure out why.

Any help is appreciated!

Edit:

Here is the entire context. It will probably be very confusing.

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());
    }
}

}

The error occurs on the line:

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

1 Answers1

0

You are using a "raw" DatedValue there. That means the compiler doesn't know a specific type for the result of getValue(), and treats it as an Object. Because the relational operator > is only defined for numeric operands, you should get a compilation error.

To fix it, specify a type parameter for your DatedValue. In fact, fix every case where you have a warning that says, "DatedValue is a raw type. References to generic type DatedValue should be parameterized."

The for-loop that is causing trouble should include a type parameter:

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

There are a number of other problems with the DateValue class.

The implements clause should be implements Comparable<DatedValue<V>>, and the compareTo() method should be declared as public int compareTo(DatedValue<V> dv). This will eliminate the raw type warnings.

If you implement Comparable, you should also override equals() and hashCode() so that they yield consistent results. That implies that your compareTo() method should fall back to comparing value when the dates are the same.

Also, you directly access fields instead of using the accessor methods you've defined. You should declare DateValue to be final so that these accessors cannot be overridden.

erickson
  • 265,237
  • 58
  • 395
  • 493