• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generic Method - passing parameters  RSS feed

 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am calling method like this...



then i have these methods...



Compiler is screaming about this line of code..



Giving me this error The method testLessThanZero(Integer) in the type QueueOfStrings is not applicable for the arguments (T)


Can anyone help me please. How to i pass Integer object to this method?

Thanks
 
Paul Clapham
Sheriff
Posts: 22835
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't. Inside that method, T is any type whatsoever. There's no way to make an arbitrary type into an Integer. Didn't we already have a discussion about this in another thread?
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes we did. That's what I am trying to do. I am trying to figure out generics that's why I am playing with this
 
Paul Clapham
Sheriff
Posts: 22835
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carry on, then.
 
Campbell Ritchie
Marshal
Posts: 56576
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are several other things I would pick up in your code.
Never say
if (something) return true; else return false;
Just say
return something;
In the case of a method to look for negative numbers it would read
return i < 0;
Never write == true or == false, which are both poor style and error‑prone.
Not
if (b == true) ...
but
if (b) ...
Not
if (b == false) ...
but
if (!b) ...
You don't actually need the b variable in line 15: you can write
if (testLessThanZero(i)) counter++;
...only with {} and proper indentation. That will not change your compiler error in the slightest; as Paul C says, you cannot turn a T into an Integer. There are only two things you can turn into an Integer: an Integer or an int by boxing conversion. Any other conversions would require an explicit cast, and the whole idea of generics is to avoid casts because they are error‑prone too.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your method testLessThanZero expects an Integer to be passed to it.

Your method countLessThanZero takes a Collection<T> - a collection of objects of an arbitrary type T. Then, in line 15, you are calling testLessThanZero and you are passing it an element from the collection. That obviously does not work, because the element of the collection could be of any type. It's not always an Integer, so you cannot pass the object of type T to a method that expects an Integer.

What would you expect to happen if you would call countLessThanZero with a Collection<String> instead of a Collection<Integer>? That should obviously not be possible.

I think you might be confused about when and where the compiler checks the types. It does NOT check the type at the point where you call the countLessThanZero method. Instead, it checks the type when it's compiling the generic countLessThanZero method itself. If you are doing anything there that is incorrect, then you get a type error there. Regardless whether you call the method only with a Collection<Integer> in some other place.

Do you have experience with C++? It seems like you are thinking the C++ way. In C++, you have templates, which do work in the way you seem to expect. In C++, the compiler generates a specific version of a template method whenever you try to call it with a specific type. But that is not how generics work in Java. Java generics are not like C++ templates - only one actual implementation of the method exists, and the compiler checks that you don't do anything illegal with the types.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So how should i pass integer to that method or rather should I change  testLessThanZero to take Generic type?
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to use generic parameter bounds. Those methods can only do their job if they have the correct type, so they should tell the outside world about it.

In order to do its job, countLessThanZero() needs a Collection of any type, it doesn't matter which, as long as those types extend the type that testLessThanZero() needs to be able to determine that it's less than zero.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:You need to use generic parameter bounds. Those methods can only do their job if they have the correct type, so they should tell the outside world about it.

In order to do its job, countLessThanZero() needs a Collection of any type, it doesn't matter which, as long as those types extend the type that testLessThanZero() needs to be able to determine that it's less than zero.

Yes as or right now countLessThanZero() does take Collection of any type and that is clear to me. I am just confused how to element to testLessThanZero() when i iterate or how do I change signature of testLessThanZero() that it takes general elements of that collection.
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stribor Kab wrote:Yes as or right now countLessThanZero() does take Collection of any type and that is clear to me.

No, it doesn't. It takes a Collection of T. T is not just any type, T is T. If you want any type, you use a generic wildcard. If you need to constrain your wildcard, you use generic type bounds. Read this part of the tutorial: https://docs.oracle.com/javase/tutorial/extra/generics/morefun.html
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Would you mind showing me an example with different code than my
 
Knute Snortum
Sheriff
Posts: 4281
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First, think about this: what class (hint: superclass) is the operation less-than (<) valid for?  Then make T extend that class.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Comparable i thinks
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote:Then make T extend that class.

T is not even required. Generic parameters are only useful if you need specific return types, or if you have multiple parameters with related types.
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stribor Kab wrote:Comparable i thinks

No, because Comparable doesn't have a concept of zero. You need a type that you can compare to zero.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then it is Integer class
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a more general case than integers.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am lost. 
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are more things you can compare to zero than just integers. For instance, rational numbers can also be compared to zero, and Java has a class that includes both integers and other rational numbers.

Check out which types Integer inherits from.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm. Number?
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aye, so now you have to rewrite testLessThanZero() so that it takes a Number, and you have to rewrite countLessThanZero() so that it takes a Collection of anything that extends Number.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Now i am stuck in testLessThanZero since I cant compare Number so I need to have Number implement Comparator. How would I do that?
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are on the right path, in fact, you almost have a working solution.

The only thing that doesn't work in your current code is that you can't do x < 0 on a Number. The < operator only works on numeric primitive types, and Number is a class, just like any other class.

Don't think too much about Comparable for now. Look at the API docs of class java.lang.Number. How could you check if the value that the Number object contains is less than zero?
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All I see from Number API is few methods that convert the values such as..




That certainly wouldnt work since we dont know what type this method will receive beside being Number??
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, but every Number knows how to convert itself to one of those values. And you can definitely do something with one of those values.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well beside those methods I mentioned above I cant think of anything...Beside Casting which is out of question of course...,.Number also extends Object and I don't see anything there either

Care to offer another clue? 
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To put it plainly, you can convert a number to one of those primitive values, and then compare that to zero.
 
Stribor Kab
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes by using one of those methods public abstract int intValue() but since we dont know what is passed to this method we dont know if we should use double doubleValue() or int intValue()
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It doesn't matter, read the class and method contracts. EVERY Number knows how to convert itself to one of those primitives. It may not always be completely accurate or precise, but EVERY Number has an exact representation for zero, so you can safely convert them to, say... double, and then compare them to 0.0.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!