0

我有其他人编写的这段代码,我很难理解它。

它工作正常并产生正确的结果,但我不明白它是如何工作的

package you;

import clowns.Clown;
import clowns.Volkswagen;

public class You {
static int counter = 0;
static Volkswagen vw = new Volkswagen();

public static void main(String args[]) {
    vw.add(new RecursiveClown());
    vw.done();
}

static class RecursiveClown extends Clown {
    public int hashCode() {
        if (++counter < 20) {
            vw.add(new RecursiveClown());
        }
        return super.hashCode();
    }
}
}

无法理解,显然RecursiveClown没有在任何地方被调用,它的hashcode()功能也没有

那么它是如何工作的并添加RecursiveClown对象。

还有为什么它会回来super.hashCode();

还有另一个类,在上面的代码中被引用。

 package clowns;

 import java.util.HashSet;
 import java.util.Set;

public class Volkswagen {
private static final int CAPACITY = 5;
private Set<Clown> clowns = new HashSet<Clown>();

public synchronized void add(Clown clown) {
    if (clowns.size() >= CAPACITY) {
        throw new IllegalStateException("I'm full");
    } else {
        clowns.add(clown);
    }
}

public synchronized void done() {
    if (clowns.size() == 20) {
        // The goal is to reach this line
        System.out.println("I'm a Volkswagen with 20 clowns!");
    }
}
}

这两个类的输出是:I'm a Volkswagen with 20 clowns!

但每当我打印

clowns.size() 

add()“大众”的方法中它总是返回 0 那么它是如何比较的

clowns.size() == 20

并将其评估为真实?

4

4 回答 4

2

为什么您的大众汽车包含的小丑数量超过其容量允许的数量,原因在于添加小丑的方式。

它基本上在行内

clowns.add(clown);

在方法中Volkswagen.add()。它首先调用hashCode要添加的小丑,然后将其添加到其内部结构中。由于再次hashCode递归调用Volkswagen.add(),此时小丑尚未添加到(内部数据结构支持)HashSet,因此size()返回 0。

这样,在方法开始时不会达到容量Volkswagen.add(),而只有在退出此方法时才达到容量(因为只有小丑才实际添加到 中HashSet)。

于 2013-06-18T06:32:09.730 回答
1

HashSet.add如 fge 所述,该函数将hashcode在添加对象之前检查对象的 ,这意味着在添加小丑#1 之前,Volkswagan.add调用小丑#2 的函数。

这一直持续到哈希码函数中有 20 次深度递归,一旦终止,所有 20 个小丑都被一次性添加。

于 2013-06-18T06:33:07.063 回答
1

Set<Clowns>a HashSet,它本身由 a 支持HashMap。所以,基本上,当你向 中添加一个对象时Set<Clowns>,它会调用HashMap.put().

HashMap.put()调用hashCode()提供的对象的方法。hashCode()这就是为什么在没有显式调用的情况下调用对象的方法的原因。

于 2013-06-18T06:31:25.920 回答
0

代码依赖于HashSet自身.hashCode()

当一个元素插入到 aHashSet中时,这个实现Set通过首先调用.hashCode()要添加的元素来确定元素的唯一性;当且仅当哈希码等于另一个时才被.equals()考虑。

它返回 super.hashCode() 因为这是Object一个:Clown不会覆盖它。

由于RecursiveClownextends Clown,可以将其添加到SetsClown中。添加一个时,.hashCode()在大众汽车中添加另一个递归小丑,直到counter达到20。

于 2013-06-18T06:28:28.407 回答