• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Please, interpret this error message

 
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Then the following:

|  Error:
|  incompatible types: inference variable R has incompatible bounds
|      equality constraints: java.util.Optional<T>
|      lower bounds: java.util.OptionalInt,java.lang.Object
|  OptionalInt optional = Arrays.asList(1,2,3,4,55,6,6,7,78,98).stream().collect(Collectors.maxBy(Comparator.comparing(m -> m)));
|                                  ^----------------------------------------------------------------------------------------------------^



Now a newbie gets confuse!  Why does OptionalInt not work where Optional<Integer> worked?  Where are the lower bounds in the above command?
 
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Moving to our Streams forum.

Not certain about what follows.
The bounds of your List are <? extends Integer>. That hasn't got a lower bound, so there is no guarantee that you can unbox one of its elements into an int. The complier doesn't check whether Integer actually has any subtypes. It therefore cannot confirm that what comes out of the List (Integers) will be an int and you therefore might not be able to create your OptionalInt. Try inserting a .mapToInt(Number::intValue) line.
I might be totally mistaken but somebody else will know.
 
Rancher
Posts: 4117
47
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Collector created by Collectors.maxBy is defined as Collector<T,A,R>, where R is Optional<T> (in this case Optional<Integer>).
That's what it's complaining about, as that drives the return value.
OptionalInt is not an Optional<T>.
 
Saloon Keeper
Posts: 3300
146
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A handy method to determine the result type of some complex Stream operation is to use the type 'var'.
For instance: var variable = <some complex opration>. Every IDE will then suggest to replacce the var for its real type. The other day I had an error which I didn't understand. I had used 'List<...> = ...', the error message was, as usual, incomprehensible, and when I used what I described, it turned out that Java had inferred the type 'ArrayList<...>'.
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Some IDEs can go one better. If you hover your mouse over the different method names, Eclipse will show a pop-up with the return type of the method, e.g. Stream<Integer>.
 
Ranch Foreman
Posts: 3268
20
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want to use primitive streams rather than object streams (e.g. IntStream and OptionalInt rather than Stream<Integer> and Optional<Integer> then it's often better to make sure you aren't introducing objects along the way accidentally.  As Dave notes above, the problem here was with the collector returning Optional<T> rather than OptionalInt.  To avoid this, try to use IntStream from the beginning - there are existing methods to help you:
 
Piet Souris
Saloon Keeper
Posts: 3300
146
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Some IDEs can go one better. If you hover your mouse over the different method names, Eclipse will show a pop-up with the return type of the method, e.g. Stream<Integer>.


Does that work for a var as well?
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Never tried it with var. I don't think I have ever used var.
 
Piet Souris
Saloon Keeper
Posts: 3300
146
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is a bit getting used to, but I find it as useful as the diamond operator in Java 7.
 
Mike Simmons
Ranch Foreman
Posts: 3268
20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
More useful than diamond. . Unfortunately we're currently stuck on Java 8 in my day job, so I don't get to use it as often as I'd like.

Regarding the Eclipse feature... IntelliJ shows return type of methods too, if you press ctrl/command while doing the mouseover.  It works the same whether you declare the variable as Stream<Integer>, Object, or val.
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
okay, so:

I am assuming that the lower bound and upper bound is the same thing - Integer.
Now, how does Java infer List<? extends Integer> form Arrays.asList(1,2,3,4,55,6,6,7,78,98) ?
I am also assuming that List<? extends Integer> means a List instance capable of containing instances of  Integer or instances of any subclass of Integer.  
1.  Which is the lower bound - the Integer class or a subclass of the Integer?
2.  Is there any subclass of the Integer class?
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:. . . 1.  Which is the lower bound - the Integer class or a subclass of the Integer?

If it is <? extends Integer> it is a subclass of Integer.


2.  Is there any subclass of the Integer class?

Have you looked at the Integer documentation and read the first line after the horizontal rule?

But . . . I looked at your code on Eclipse; if I hover over where it says asList, it says <Integer>………List<Integer>.
If I hover over where it says stream(), it says Stream<Integer>.
If I hover over where it says collect, it says <Optional<Integer>, Object>………Optional<Integer>.
So the lowest bound is List<Integer>/Optional<Integer>

As you have been told, you cannot simply unbox something from a List<Integer> into an OptionalInt.
 
Mike Simmons
Ranch Foreman
Posts: 3268
20
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Biniman Idugboe wrote:. . . 1.  Which is the lower bound - the Integer class or a subclass of the Integer?

If it is <? extends Integer> it is a subclass of Integer.


In the expression <? extends Integer> there is no lower bound.  The upper bound is Integer.

The ? may evaluate to be a subclass of Integer, or it may be Integer itself.  Note that and expression like <? extends Integer> does not necessarily mean that a subclass of Integer actually exists.  

Backing up though...

Biniman Idugboe wrote:Now, how does Java infer List<? extends Integer> form Arrays.asList(1,2,3,4,55,6,6,7,78,98) ?


I don't see anywhere that the type is inferred as List<? extends Integer>.  It's List<Integer>, with no wildcard.  Perhaps this idea came from earlier in the conversation:

Campbell Ritchie wrote:The bounds of your List are <? extends Integer>.


This was not correct.  Campbell noted he was uncertain at the time, and as it turns out, this was mistaken.  Arrays.asList(1,2,3,4,55,6,6,7,78,98) returns a List<Integer>, period.
 
Piet Souris
Saloon Keeper
Posts: 3300
146
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Indeed. If still in doubt, try

and see if the compiler complains.
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
jshell> Arrays.asList(1,2,null);
$1 ==> [1, 2, null]
|  created scratch variable $1 : List<Integer>
So, what is the meaning of this?  Has null become an instance of Integer?
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:. . . So, what is the meaning of this?

It means you are creating a different List

Has null become an instance of Integer?

No. But most Lists can accommodate nulls; after 1 and 2, that must be an Integer reference pointing to null. What you would get if you added the elements in the order null, 1,  2? I don't know. Maybe a List<Object>. Not certain.
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

So, if you only knew that a list is List<Integer> and you have no idea of the actual contents, does it not mean that it is simply unsafe to fetch an item from the list and assign the item to a type other than the Optional type?  What are the benefits of allowing a null in a list?
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You might find that easier if you didn't provoke an exception by trying to unbox null.
 
Sheriff
Posts: 6034
157
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:So, if you only knew that a list is List<Integer> and you have no idea of the actual contents, does it not mean that it is simply unsafe to fetch an item from the list and assign the item to a type other than the Optional type?


Integer is a class (not a primitive like int) and so it may be null.  Just as any variable of type Integer will need to handle nulls, so will a List of Integers.

What are the benefits of allowing a null in a list?


One I can think of is to model missing parts of the List.  But I'm not sure it's the List allowing nulls so much as a null is a valid value of Integer.
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see several mention of IDEs, but I am not using any IDE.  I am using notepad. In fact, I have not used any IDE so far. I can even go a step further to say that I do not know how to use the IDEs yet.  My first priority is to understand the rudiments so that I will not depend on IDEs to tell me the basic things I ought to know.
Going forward, some of the little things are quickly becoming something major, for me, that is.  Example:

I wish to know the full and correct meaning of so that I can write code that uses maxBy() method without relying on IDE to help me out.  Do not laugh!  At this moment, my understanding of ? super T is that it means any subclass of a class.  That is, the class must have a superclass.  The Object class, for example, does not have a super class. That should mean that Comparator<Object> is invalid, but that's not true.

My understanding is flawed.  Now, I appeal.  Who can explain the meaning of ? super T in a simple to comprehend manner?
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Moderator. It looks like I am seeing double now.  I thought I saw a post from a user named inspire sayan, talking about feedback of Eclipse IDE.  That post has suddenly disappeared.  Did I overwrite it?
 
Mike Simmons
Ranch Foreman
Posts: 3268
20
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:At this moment, my understanding of ? super T is that it means any subclass of a class.  That is, the class must have a superclass.  The Object class, for example, does not have a super class. That should mean that Comparator<Object> is invalid, but that's not true.


<? super T> means any superclass of T, or T itself.  So <? super Object> really just means Object.

For comparison, <? extends T> means any subclass of T, or T itself.  So both <? extends T> and <? super T> include T itself.
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:. . . inspire sayan . . . That post has suddenly disappeared.

That is because an eagle‑eyed mod called Ganesh Patekar noticed the spam links hiding behind the punctuation marks. And the cheeky so‑and‑so posted the same as I had posted earlier We haven't got a smilie bad enough for that.

Did I overwrite it?

No. But you probably are seeing double
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks to everyone that has responded so far.  However, I will like to return to the error message that formed the basis for this thread.

|  Error:
|  incompatible types: inference variable R has incompatible bounds
|      equality constraints: java.util.Optional<T>
|      lower bounds: java.util.OptionalInt, java.lang.Object
|  OptionalInt optional = Arrays.asList(1,2,3,4,55,6,6,7,78,98).stream().collect(Collectors.maxBy(Comparator.comparing(m -> m)));
|                                  ^--------------------------------------------------------------------------------------------------------------------^


I suppose the inference variable R is talking about OptionalInt optional.  OptionalInt extends Object, meaning the upper bound is Object and the lower bound is OptionalInt.
The right hand side of the assignment statement returns an instance of Optional<T>.  Optional<T> extends Object, meaning the upper bound is Object and the lower bound is Optional<T>.  
I would have thought the lower bounds are java.util.OptionalInt, java.util.Optional
The error message says lower bounds: java.util.OptionalInt, java.lang.Object
Please, explain the concept of lower bounds.
 
Knute Snortum
Sheriff
Posts: 6034
157
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can't explain the error message, but it looks like Option<Integer> and OptionalInt are not related except by Object, so I wouldn't expect the return value of one to be compatible with the other.

You would think that:
But no, they both inherit directly from Object.
 
Dave Tolls
Rancher
Posts: 4117
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:
You would think that:
But no, they both inherit directly from Object.



OptionalInt does not extend Optional because OptionalInt (as with OptionalDouble and OptionalLong) is an optional for a primitive int, which cannot be an extension of Optional<T> for (hopefully) obvious reasons.
 
Campbell Ritchie
Marshal
Posts: 64689
225
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:. . . But no, they both inherit directly from Object.

They woud have to, since the Java8 chappies saw sense and started making lots of classes immutable.

The Optional documentation wrote:public final class Optional<T>
extends Object

My emphasis and link.
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My interest is still on the error message:

|  Error:
|  incompatible types: inference variable R has incompatible bounds
|      equality constraints: java.util.Optional<T>
|      lower bounds: java.util.OptionalInt, java.lang.Object
|  OptionalInt optional = Arrays.asList(1,2,3,4,55,6,6,7,78,98).stream().collect(Collectors.maxBy(Comparator.comparing(m -> m)));
|                                   ^--------------------------------------------------------------------------------------------------------------------^

 
I have decided to explain it in the way that suits me.  Anybody is free to laugh this time. Even so, I expect that you, being a concerned citizen of this forum, will make corrections to the explanations.
Explanation of error message:
1. incompatible types: inference variable R has incompatible bounds.  // the inference variable in the above statement is OptionalInt opt.  This line of the error message is simply complaining about the fact that the  left hand side of the statement is not compatible with the right hand side.  The right hand side is returning an instance of Optional<Integer> and trying to assign it to a target declared for an instance of OptionalInt.  The solution is either to change the left hand side to Optional<Integer> opt or change the right hand side to return an instance of OptionalInt.
2. equality constraints: java.util.Optional<T>   // meaning the left hand side of the statement should be Optional<T> instead of OptionalInt because the type of variable on the left hand side is constrained by or limited by or dependent on the type of instance returned by the right hand side.
3. lower bounds: java.util.OptionalInt, java.lang.Object   // meaning that left hand side, being the lower bound of the statement, has a definition that says OptionalInt extends Object.  The fully qualified name of OptionalInt is java.util.OptionalInt.  The fully qualified name of Object is java.lang.Object.  The summary is that the two classes are not compatible with the class of instance returned by the right hand side of the statement.  Now, since we already know that OptionalInt opt cannot be the target of an instance of Optional<Integer>, can we try the superclass of OptionalInt instead?  The superclass of OptionalInt is the Object class.  
So,

should work.  However, it does not work, unless the right hand side is cast to Object.  But the statement that caused the error did not cast the right hand side to Object.  So, Java had to report the error.  See next line!


If my self serving explanations are anywhere near correct, then from this point forward, I will look closer at error messages because they actually make a lot of sense.
 
Knute Snortum
Sheriff
Posts: 6034
157
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:I have decided to explain it in the way that suits me.  Anybody is free to laugh this time. Even so, I expect that you, being a concerned citizen of this forum, will make corrections to the explanations.  


No one is laughing at you.  But I do think there is some trouble in communication.

You explanation seems fine to me.  But I'm not sure why you are trying to coerce the left-hand variable to an Object.  Isn't the answer to declare the variable type Optional<Integer>?
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am not suggesting that anybody is laughing at me.  Recall that earlier in this thread, I asked that nobody should laugh as a result of what I was about to say.  You know, there are somethings that can make you laugh even if you didn't want to laugh.  Some things could be so ridiculous or perhaps, so funny that they are laughable.  Yeah!  I am trying to get understanding, so I will not be offended if my statements provoke laughter.
Now, the reason I used

is because one of the lower bounds reported by the error message is java.lang.Object.  I just wanted to be sure that when the right hand side of the statement is cast to Object, the statement will execute without error.
 
Mike Simmons
Ranch Foreman
Posts: 3268
20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Biniman Idugboe wrote:

should work.  However, it does not work, unless the right hand side is cast to Object.  But the statement that caused the error did not cast the right hand side to Object.


When I try this, it does work.  There's no need to cast anything to Object - the thing returned by Arrays.asList() already is an Object.

Now, it's difficult to do anything else with "opt" as an Object, unless you just want to call toString() or equals() or hashCode()... or unless you cast it or assign it to something more useful.  List, say, Optional<Integer>.

I do like your attitude about understanding exactly what the error messages mean.  It's true that often they seem unhelpful (especially when generics and lambdas are present), and yet they may contain important clues about what's going on.  And sometimes they are telling you exactly what you need to know.  So, good for you!
 
Biniman Idugboe
Ranch Hand
Posts: 229
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!