简体   繁体   中英

Why can't I use .pollFirst() method for a Set that was initialized as a TreeSet?

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM