Both the Integer and Double objects extend Number. So you could do the following:
public static Number sum (Stack<Number> stack) {
Note that this method will require you to check if the numbers are Integers or Doubles.
Also, remember that you can't use the + operation to add objects.
darkagn
Veteran Poster
1,197 posts since Aug 2007
Reputation Points: 404
Solved Threads: 200
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Why create a new stack in these methods. Just iterate thru the stack and add the elements?
int sum = 0;
for (int i: stack) {
sum += i;
}
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
Here part of a possible solution.. the following compiles OK
public <T> T sum(Stack<T> stack) {
T sum; // really want to say T sum= 0;
for (T num : stack){
// can't do this: sum += num;
}
return sum;
}
ie, that's how you declare a method to take a Stack of Somethings, and return a Something result. What I can't figure out is how to do arithmetic on the Somethings. You can declare as , which is closer to the right spirit, but still doesn't get you any arithmetic capabilities. Ideas anyone?
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
It does get you arithmetic capabilities from within another class where you instantiate an Object of that generic class.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Hi BJSJC. What I mean is that with a variable defined as generic type all you can access at compile time are the methods defined on Number itself, which do not seem to include any arithmetic functions. Do you know of another class that we could use to restrict so that it includes Integer and Double and also gives arithmetic?
James
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
With the class you have defined, you can use something like. .
public int addInteger(){
int result = 0;
for (T i: numbers){
Integer j = (Integer)i;
result+=j;
}
return result;
}
This is where 'numbers' is defined as an ArrayList.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Yes, you can do that, but what when you want to return a value of type T? If you define the result as Integer, that's OK, you can then do the same thing for Double, that's OK too, now you have overloaded methods that will work, but that's not what the OP was asking.
You can try this
public <T extends Number> T sum(Stack<T> stack) {
Integer sum = 0;
for (T num : stack){
Integer n = (Integer) num;
sum += n;
}
return (T) sum;
}
and hope that if happens to be Double then the value won't overflow, or do the same thing with Double temp variables, and hope there's no rounding problems, and no runtime cast errors...
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
What you want to do does not make sense then. You wouldn't expect the ArrayList class, which is generic, to add up all of the numbers in the array for you. The purpose is to provide a container, not to have specific implementations.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Sorry, obvious misunderstanding here. The method does the addition, or tries to, but is stymied by the problem of doing arithmetic on generic types.The ArrayList bit is almost irrelevant. The quest is to write a method that takes a generic parameter type, performs some arithmetic on it, and returns a result of the same type. Sure you can write n overloaded methods, but to OP wanted to know if there was a single method solution using generics. (ps, I don't think there is).
J
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
You can write an equivalent method that takes an array of Doubles. James' comment was making the point that by doing so, you are not really writing "generic" code. Generic code should provide methods that can work for any type of Object. Hence, it is "generic". If you read the lectures you'll gain a better understanding of what I'm talking about.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
I didn't know the extended for loop is applicable to stacks and queues
Yes, it works for everything that implements the Collection interface. In fact the code I posted can have the parameter as Collection rather than Stack and will then be more widely useful.Regarding your proposed solution - it almost works. It works fine with Integers the way you posted it, however it gives a runtime error if I pass a Double to it:
That's right - as I said "hope there's... no runtime cast errors" and after a bit more thought I'm even more convinced there is no sensible way to do what you ask. The only polymorphic way to do addition is via the + operator, that only works on primitives (int, double etc), but generics can only be reference types (Integer, Float etc)
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
That's right - as I said "hope there's... no runtime cast errors" and after a bit more thought I'm even more convinced there is no sensible way to do what you ask. The only polymorphic way to do addition is via the + operator, that only works on primitives (int, double etc), but generics can only be reference types (Integer, Float etc)
I think that if you use Number class instead of T, you can call methods such as doubleValue() and intValue(), then use the + operator and finally return either an Integer or Double. Number is an abstract class that both of these classes extend, so the true polymorphic method of doing what is required would be to use a Stack and return Number.
darkagn
Veteran Poster
1,197 posts since Aug 2007
Reputation Points: 404
Solved Threads: 200
Hi Darkagn
Problem here is that Number is an abstract class, so you would have to chose a subclass (eg Integer) to instantiate a value to return. Number only has the xxxValue() methods, so you can't do much with it unles you know what subclass it really is. If the original data is Double, you need to calculate & return Double, ditto Integer, and there's no way I know to do that without explicitly coding both those cases - unless you have a better idea???
J
JamesCherrill
Posting Genius
6,371 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
So in Java you can't declare that you will return an object of type Number, but actually return an Integer or Double (since they are subclasses)? Is that correct?
darkagn
Veteran Poster
1,197 posts since Aug 2007
Reputation Points: 404
Solved Threads: 200
No, that is not correct. You can return any subclass of Number if the return type is declared as Number. But the point made earlier still stands.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
No, that is not correct. You can return any subclass of Number if the return type is declared as Number.
If that is the case then I think my logic should work. If the method signature was like this:
public Number stackSum(Stack<Number> numbers)
Then I think it should be possible to have one method for both Integer and Double objects.
darkagn
Veteran Poster
1,197 posts since Aug 2007
Reputation Points: 404
Solved Threads: 200
It is possible, but first, you have to verify the Object's type, then cast it. That isn't Generic code.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354