0

I want to have a method which calculates the mean of a LinkedList of type Integer, Double and Float.

The problem is the sum += i; statement, since java says that the + operator isn't defined for type Object.

I could do a cast, but if the LinkedList was of type Float, for example, and the cast was to Integer, I would be not computing the correct mean.

What should I do? Thanks.

 public double mean (LinkedList<?> l)
 {
  double sum = 0;
  int n = 0;
  for (Object i : l)
  {
   n++;
   sum += i;
  }

  return sum / n;
 }
nunos
  • 20,479
  • 50
  • 119
  • 154
  • 3
    You shouldn't require a `LinkedList` because everything you do is iterating of the elements in `l`. Just use `Iterable extends Number>`. – whiskeysierra Sep 26 '10 at 19:38

5 Answers5

11

You should restrict your list to Numbers. That is the common superclass for Integer, Float, Double and other numeric types. It has no operators defined, only conversion methods to e.g. double, but that is enough for you here:

 public double mean (LinkedList<? extends Number> l)
 {
  double sum = 0;
  int n = 0;
  for (Number i : l)
  {
   n++;
   sum += i.doubleValue();
  }

  return sum / n;
 }
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • This whole ` extends Number>` happened while I was off using Ruby. What is this construct called? Does this syntax `LinkedList>` say we have a LL of unknown type, and `LinkedList extends Number>` is a LL of unknown types each guaranteed to be subclassed from Number? – Tony Ennis Sep 26 '10 at 19:21
  • and why not `LinkedList ` ? – Tony Ennis Sep 26 '10 at 19:23
  • 1
    To answer your first question: Yes, using `LinkedList>` specifies a linked list containing elements of unknown type (they are at least objects) and `LinkedList extends Number>` may contain elments of any subtype of Number (and if nobody is doing strange reflection hacks, it gaaranteed). Why not using `LinkedList`? It ties the users of your api to a specific type. You can't pass in a `LinkedList`. In fact there is no need to even required LinkedList, the best way would be to require an `Iterable extends Number>`. – whiskeysierra Sep 26 '10 at 19:36
  • 1
    @Tony, this is called a _wildcard with extends_. `LinkedList extends Number>` matches any list of a subclass of `Number`. I.e. it can be a `LinkedList`, a `LinkedList`, a `LinkedList` etc. It is important to note that the latter are _not_ subclasses of `LinkedList` - that's why the wildcard is needed here. – Péter Török Sep 26 '10 at 19:37
  • @Willi, if you want to reflect to someone else's comment, it is recommended to include his nick preceded by a @ in your answer (e.g. @Tony) - otherwise he won't get notified about your comment. – Péter Török Sep 26 '10 at 19:58
  • @willi @Péter Török Thanks for the info! I'll get to googling on it. – Tony Ennis Sep 26 '10 at 22:23
1

The only option would be to generalize on java.lang.Numberbut it wouldn't actually help much as you can't unbox a Number to anything which can be applied to the primitive arithmetic operators. So you'll still have to check for each of the Number-types and call Number.doubleValue, intValue and so forth on the Number-object.

Alexander Sagen
  • 4,028
  • 1
  • 18
  • 15
0
public <T extends Number> double mean (LinkedList<T> l) {
  double sum = 0;
  int n = 0;
  for (T i : l)  {
    n++;
    sum += i.doubleValue();
  }

  return sum / n;
}
Samuel García
  • 2,199
  • 14
  • 21
0

In Java, generic collections are contravariant. This means that if you have parent class A and class B which extends A, then you cannot make something like List<A> list = new LinkedList<B>();.

But there is a possibility to allow this type of substitution: you can use a construction like List<? extends A> list = new LinkedList<B>();. For your case:

 public double mean (List<? extends Number> l)
 {
  double sum = 0;
  int n = 0;
  for (Object i : l)
  {
   n++;
   sum += i;
  }

  return sum / n;
 }
Roman
  • 64,384
  • 92
  • 238
  • 332
0

Here's a couple of things to consider.

  1. Allow Collection instead of only lists
  2. You don't need a separate variable 'n', just use l.size()
  3. Watch out for empty/null input
BillRobertson42
  • 12,602
  • 4
  • 40
  • 57