1

I have the following method:

  private <E extends Number> void AddOne(ArrayList<E> al, Double num) {
      al.add(num);
  }

al.add(num) doesn't work. What is the best way I can insert a number into a generic Number Array?

So basically, I have a generic

ArrayList< E > al

And I want to insert a numeric value in it, how can I do this? (I remember C++ being a lot easier -_-)

NomenNescio
  • 2,899
  • 8
  • 44
  • 82
  • 2
    Doesn't work means? What you are expecting and what you got? Without those details it is hard to answer any question. – kosa Jan 30 '12 at 20:04
  • 2
    Your `ArrayList` is a list of E's, so what you can insert in it must be an E or a subclass. `Double` is a `Number`, but it isn't necessarily an E; you'd have to cast it to an E for this to work. Is this really the signature you need? – Chris Nash Jan 30 '12 at 20:08
  • What about ArrayList without "extends"? – Luciano Jan 30 '12 at 20:08
  • Answers: 1) http://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java 2) http://stackoverflow.com/questions/2776975/how-can-i-add-to-list-extends-number-data-structures – bchetty Jan 30 '12 at 20:23

5 Answers5

3

You can't add anythig to this list, because you don't know what type it really is.

Consider inheritance tree like this:

Number
|
|- BigInteger
            |
            |- NonNegativeInteger
                                |
                                |-PositiveInteger

You say that your list is list of elements which inherits from Number. Ok, so suppose you want to add Number to a list, but wait you could have List<BigInteger> and you cannot put Number into it.

Ok, so you could put BigInteger, right? No! Because your list could be List<NonNegativeInteger>. And the story goes on and on...

Declaring list as List<T extends SomeObject> ensures you that when you get something from list it's of type SomeObject. Nothing else is known.

So how to avoid the problem? Just remove the template.

List<Number>

And now you can put anything what inherites from Number.

Or, what is even better in your case, change Double to E:

private <E extends Number> void AddOne(ArrayList<E> al, E num) {
  al.add(num);
}
msi
  • 2,609
  • 18
  • 20
  • 1
    +1 for good explanation, and as a side note, you could use ArrayList super Number> al and then use it to store Numbers. – wmz Jan 30 '12 at 20:47
2

You should change your add to:

  private <E extends Number> void AddOne(ArrayList<E> al, E num) {
      al.add(num);
  }

and then in any concrete instance of your generic class, where E resolves to a specific number class, you'll be able to add numbers of that type.

Don Roby
  • 40,677
  • 6
  • 91
  • 113
2

Your method makes no sense. You want to add a Double to an ArrayList that is defined as holding any class that extends Number.

What happens if the array you pass in is ArrayList<Integer> and you try and add your Double to it?

If you're only interested in having an ArrayList that holds things that are subclasses of Number, you don't need generics in your method; simply use an ArrayList<Number>

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
1

Do you mean this?

 private void AddOne(ArrayList<Number> al, Double num) {
      al.add(num);
  }
1

I think that what you really want is:

private void AddOne(ArrayList<Number> al, Double num) {
     al.add(num);
}

Otherwise you can't add anything to the List with adding the cast to E