Operadores genéricos de Java

Tengo el siguiente método:

  private <E extends Number> double GetAverage(ArrayList<E> al)
  {
    double total = 0;
    Iterator<E> itr = al.iterator();
    while(itr.hasNext())
    {
      total += itr.next();
    }

    return total;
  }

but it does not compile. I get a

"total cannot be resolved or is not a field"

"total += itr.next();"

I understand that Java doesn't know the value of E, but I hope you understand what I mean, what is the best way to create a generic method that adds the total(Numeric values) of an ArrayList.

preguntado el 30 de enero de 12 a las 19:01

Qué está haciendo retVal in your example? Did you mean total? Do you use any IDE like Eclipse or Netbeans? -

4 Respuestas

There's actually syntax errors with your code, you have line that's not complete. Your full code should be:

private <E extends Number> double GetAverage(ArrayList<E> al) {
    double total = 0;
    Iterator<E> itr = al.iterator();
    while (itr.hasNext()) {
        E next = itr.next();
        total += next.doubleValue();
    }

    return total;
}

Note: the return of 'total' and not undefined retVal

Respondido el 30 de enero de 12 a las 23:01

Tu código se ve así:

itr.next().
total += itr.next();

Which the compiler is reading as this:

itr.next().total += itr.next();

The compiler is suggesting that there is no field named total that is accessible on Number. You probably meant to not have this line:

itr.next().

On another note, I am not sure that Number will auto-unbox into a double. You may need to call Number#doubleValue() al Number ejemplo.

total += itr.next().doubleValue();

Respondido el 30 de enero de 12 a las 23:01

You can't add a generic Number a una double. There's no way to store BigInteger or BigDecimal dentro de una double field, so addition is just not definable on (doubleNumber).

Trata

total += itr.next().doubleValue();

if you can safely assume that the numbers are reducible to double without too much loss of precision.

To make your code properly generic, try this:

private <E extends Number> double GetAverage(Iterable<E> list)
{
  double total = 0;
  for (E num : list) {
    total += num.doubleValue();
  }
  return total;
}

Si quieres tratar null as a NaN value instead of failing with an exception you will have to do that with an if dentro del bucle.

Respondido el 30 de enero de 12 a las 23:01

You have an extraneous line in the code - the first itr.next() line (that ends with a dot). Also, you can't add a Number, you need to add the doubleValue. Finally, you need to return total, not retVal.

p.ej

 private <E extends Number> double GetAverage(ArrayList<E> al)
   {
     double total = 0;
     Iterator<E> itr = al.iterator();
     while(itr.hasNext())
     {
       total += itr.next().doubleValue();
     }

     return total;
   }

Since all Numbers have getDouble, you could simplify things by using the new for() iterator.

private <E extends Number> double GetAverage(Collection<E> al)
   {
     double total = 0;
     for (Number n : al)
       total += n.doubleValue();

     return total;
   }

Depending upon details, you might be able to get rid of the E extends Number stuff and just say Number...

And, definitely change the input parameter from ArrayList<E> a List<E> o incluso Collection<E>, as I did in the second example.

Respondido el 30 de enero de 12 a las 23:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.