简体   繁体   English

为什么不能对初始化为TreeSet的Set使用.pollFirst()方法?

[英]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初始化为新的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. 而且我想使用.pollFirst()方法,因为我很懒,我也不想使用temp变量,因为我有这个方便的方法,可以减少3-4行代码1行。

However, with the following code, the only way to compile my code would be to specifically call foo a TreeSet . 但是,使用以下代码,编译我的代码的唯一方法是专门将foo称为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 ? 那么,为什么Java没有意识到foo实际上是一个TreeSet呢? Should I just cast it as TreeSet if I didn't want to intialize foo as a TreeSet ? 如果我不想将foo初始化为TreeSet是否应该将其转换为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. 这样就可以在初始化时不显式调用它的TreeSet进行编译。

That's because Set doesn't define a pollFirst() method, it is defined by NavigableSet , which is implemented by TreeSet . 这是因为Set没有定义pollFirst()方法,而是由NavigableSet定义的,而NavigableSet是由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, 另一方面,要回答您的问题,我可以想到的一个很好的理由就是让Java表现出这样的效果,即假设以后在您的代码中执行类似的操作,

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. 其中, ExternalLibraryClass是任意库中的任意类,而getUnknownSetImplementation()是返回Set实现的任意方法。 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. 重要的是您的编译器无法访问该库的源代码,因此它不知道每次调用getUnknownSetImplementation()都将返回什么Set实现。

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?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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