Say I've intialized a Set
as a new TreeSet
:
Set<Integer> foo = new TreeSet<Integer>();
And I want to use the .pollFirst()
method, because I'm lazy and I don't want to have to use a temp variable because I have this handy method that would reduce what would otherwise be 3-4 lines of code to 1 line.
However, with the following code, the only way to compile my code would be to specifically call foo
a TreeSet
.
while (foo.size() > 1) {
int lower = foo.pollFirst();
int higher = foo.pollFirst();
foo.add(higher - lower);
}
So why java doesn't realize that foo
is actually a TreeSet
? Should I just cast it as TreeSet
if I didn't want to intialize foo
as a TreeSet
? Or would it be better to just intialize it that way?
Further Testing with Casting:
while (foo.size() > 1) {
int lower = (int) ((TreeSet) foo).pollFirst();
int higher = (int) ((TreeSet) foo).pollFirst();
foo.add(higher - lower);
}
This makes it compile without explicitly calling it a TreeSet
upon intialization.
That's because Set
doesn't define a pollFirst()
method, it is defined by NavigableSet, which is implemented by TreeSet
. On the other hand, to answer your question, one good reason I can think of for java to behave like that, is this, assume that later in your code you do something like this,
Set<Integer> foo = new TreeSet<Integer>();
...
foo = ExternalLibraryClass.getUnknownSetImplementation();
// At this point, how would the compiler know what 'foo' actually is?
where ExternalLibraryClass
is an arbitrary class from an arbitrary library and getUnknownSetImplementation()
is an arbitrary method that returns a Set
implementation. The important thing is that your compiler does NOT have access to the library's source code, therefore it does NOT know what Set
implementation will be returned every time getUnknownSetImplementation()
gets called.
SOME MORE ILLUSTRATION
Assume,
String whichSet = externalWebService.whichSetShouldIUse();
if(whichSet.equals("HashSet"))
foo = new HashSet()<>;
else if(whichSet.equals("TreeSet"))
foo = new TreeSet()<>;
// At this point, how would the compiler know what 'foo' actually is?