java - 创建扩展哈希集/继承的计数类

标签 java collections hashset

如果我们考虑以下类来计算添加到 HashSet 中的对象:

public class CountingHashSet<E> extends HashSet<E> {

    public int addCount = 0;

    @Override
    public boolean add(E e) {
     addCount +=1;
     return super.add(e);
    }

    @Override
    public boolean addAll(Collection<? 
    extends E> c) {
     addCount += c.size();
     return super.addAll(c);
    }

然后,JUnit 测试失败了:

@Test
public void testCount() {
    CountingHashSet<Integer> s = new CountingHashSet<>();
         s.addAll(Arrays.asList(1, 2, 3, 4, 5));
    for (int i = 6; i <= 10; ++i)
        s.add(i);
 assertEquals(10, s.addCount);
}

我得到以下信息:

java.lang.AssertionError: expected:<10> but was <15>

为什么我得到 15?在我看来,s.addAll(myCollection) 调用 super.addAll(c),如果我查看 hashSet 的源代码,我看到addAll(c) 调用 add(e) 来添加每个元素。但是为什么super.addAll(c)调用我重新定义的add方法呢? (这就是为什么我得到 15 而不是 10)

最佳答案

您将继承视为组合。它不是。调用最终不是“HashSet 上的add()”——它们最终是“当前对象上的add()” ".

But why super.addAll(c) call the add method that I redefined ?

因为这就是虚拟方法的行为方式。 addAll 只是调用 add(),它将使用实际类型中最重写的实现。这就是多态性总是 的工作原理。让我们写一个更简单的例子:

class Superclass {
    public void foo() {
        bar();
    }

    public void bar() {
        System.out.println("Superclass.bar()");
    }
}

class Subclass extends Superclass {
    @Override
    public void bar() {
        System.out.println("Subclass.bar()");
    }
}

public class Test {

    public static void main(String [] args) {
        Superclass x = new Subclass();
        x.foo(); // Prints Subclass.bar()
    }
}

Subclass.bar() 的结果是您期望从此示例中得到的结果吗?如果是这样,您认为您的版本会有什么不同?仅仅因为您正在调用 super.addAll() 并不意味着该对象突然处于“非覆盖”模式或类似模式。

关于java - 创建扩展哈希集/继承的计数类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16426752/

相关文章:

java - 如果线程使用不同的键,是否需要 ConcurrentHashSet?

java - 在java中使用字符串元素对集合进行排序

Java Hashset 返回 false 而不是 true

java - 通过 BlazeDS 从 Java 到 Flex 的自定义编码

Java String - 包含被 'offset' 隐藏的部分

java - 用将元素映射到元素集合来替换多重映射

java - 从集合中查找重复项的最快方法是什么

Java HashMap/HashSet 多态性

java - 带有本地化模式的 SimpleDateFormat 非法模式字符错误

java - Stream.collect(groupingBy(identity(), counting()) 然后按值对结果进行排序