开发者

Simple Java generics question

开发者 https://www.devze.com 2023-01-18 03:48 出处:网络
I want to have a method which calculates the mean of a LinkedList of type Integer, Double and Float.

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 + ope开发者_StackOverflow中文版rator 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;
 }


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


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.


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


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消