关于继承HashSet的疑问

问题描述

先贴代码,然后再说我的疑问:public class Concrete<E> extends HashSet<E> {private static final long serialVersionUID = 8191406567257721779L;private int count = 0;public Concrete() {}public Concrete(int initCapacity, float loadFactor) {super(initCapacity, loadFactor);}@Overridepublic boolean add(E e) {count++;return super.add(e);}@Overridepublic boolean addAll(Collection<? extends E> c) {count += c.size();return super.addAll(c);}public int getCount() {return count;}public static void main(String[] args) {Concrete<String> c = new Concrete();System.out.println(c.getCount());c.addAll(Arrays.asList("123", "456", "44444"));System.out.println(c.getCount());}}为什么我复写了addAll方法之后,然后getCount返回的不是3而是6????我方法都重写了,不明白!!!希望大侠给我给个详细的解释。 问题补充:可能是我没表述明白,我知道HashSet中的addAll是用调用add来实现的,但是我就是搞不明白,即使我这样写:@Override public boolean addAll(Collection<? extends E> c) { count += c.size(); return true;} count的值还是3,为什么我复写了addAll方法,应该是调用我子类的逻辑。跟hashSet中的addAll好像是没什么关系啊。?

解决方案

因为HashSet里面addAll是通过all来实现的。所以当你调用return super.addAll(c); 这句话时,add方法被调用了3次,所以你的count又自加了3次,因此就变成六了。。建议你把count += c.size(); 这句话去掉。
解决方案二:
你是指你原来的代码还是修改后的代码?如果是原来的代码的话,因为你最后return的是super.addAll(c); 是你自己调用了父类HashSet的方法。如果是修改后的代码,没有调用HashSet的方法啊
解决方案三:
@Override public boolean addAll(Collection<? extends E> c) { count += c.size(); return true; } 你改成这样肯定是3啊。。对的啊。。c.size()就是3啊。
解决方案四:
public boolean add(E e) { count++; //打一个断点return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { count += c.size(); //打一个断点return super.addAll(c); }鼠标右键 debug as -> Java Application 运行一下 自己看看他的运行顺序就知道。
解决方案五:
这种情况下,最好不要用继承,使用组合。让Concrete持有一个HashSet成员。Effective Java 上有,LZ可以好好看看

时间: 2024-10-03 16:39:33

关于继承HashSet的疑问的相关文章

对于继承的一些疑问,请大神解答

问题描述 publicclassJiChengextendsFulei{/***@paramargs*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubnewJiCheng().go();}publicvoidgo(){System.out.println("zilei");}}classFulei{privatefinalvoidgo(){System.out.println("fulei&q

Java集合框架详解

这篇文章详细对比以及分析了Java的集合框架的原理使用以及比较. ArrayList ArrayList就是传说中的动态数组,就是Array的复杂版本,它提供了如下一些好处:动态的增加和减少元素.灵活的设置数组的大小-- ArrayList底层是数组,并且add remove指定位置元素的时候,是通过memcpy来实现的.我们直接来看源码: ArrayList源码分析: 123456789101112131415161718192021222324252627282930313233343536

为什么Set及子类中没有提供随机取元素的方法

问题描述 在List中提供了get等方法来实现随机取在容器中的元素,但是,为什么在Set中没有提供呢,如果要在Set及子类中实现随机读取元素,该怎么操作,不可能自己去遍历或将Set存到List中去吧. 解决方案 1.可以用Set的一下两个方法获取可以随机访问的数组:引用 Object[] toArray() 返回一个包含 set 中所有元素的数组. <T> T[] toArray(T[] a) 返回一个包含 set 中所有元素的数组:返回数组的运行时类型是指定数组的类型. 2.可以继承Hash

spring mvc中javaConfig配置问题

问题描述 spring mvc中javaConfig配置问题 spring mvc中关于继承AbstractAnnotationConfigDispatcherServletInitializer的疑问 public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ @Override protected Class<?>[] getRootConfigClas

继承-关于C++开发的疑问(QT开发)

问题描述 关于C++开发的疑问(QT开发) 有个问题一直困惑着我,关于C++封装方面的. 最近在做一个使Qt网络通信的项目,首先是用QTcpServer对象进行监听,当有链接请求时,创建一个QTcpSocket对象来处理链接,这个处理主要是对对方传过来的数据按XML格式进行解析 这里有个疑问: 我是对QTcpSocket进行继承,写了一个自己的套接字类,然后把解析XML数据的代码封装在这个类里面. 但是我看同事是自己创建了一个类,把QTcpSocket作为这个类的成员,然后在这个类里面对XML数

c++ 容器与继承-c++继承中拷备构造函数调用的疑问?

问题描述 c++继承中拷备构造函数调用的疑问? class Base { public: Base() { cout << "Base()" << endl; } Base(const Base&) { cout << "Base(const Base&)" << endl; } ~Base() { cout << "~Base()" << endl; } }

继承-求大神回答我的疑问,这是关于多态的解释

问题描述 求大神回答我的疑问,这是关于多态的解释 鸟类封装了 翅膀类和moo方法:另外有两个类都继承鸟类并重写了moo方法,分别是鹦鹉和麻雀如下: 鹦鹉类: public class Parrot extends Bird{ public void moo(){ System.out.println("鹦鹉的叫声"); } } 麻雀类: public class Sparrow extends Bird{ public void moo(){ System.out.println(&q

对于Java中的接口实现多继承的疑问

问题描述 目前的理解接口:Interface   的作用就是包含一些抽象方法   然后再其他类中implement接口并override这些抽象方法        感觉纯粹只为了达到统一的方法名访问而作这么个抽象方法,跟直接在类中创建这么一个方法没啥区别      如果要做到像extend那样不重写方法就能使用父类的方法,Interface还是不行啊   实现的多继承也就变成了重写多个接口中的抽象方法,没有那层继承的意义啊 解决方案 嘿嘿,看看大师们是怎么用interface的.多看看设计模式,

关于HashSet的一些疑问

问题描述 最近使用HashSet时,才知道对于HashSet的类我一点也不了解.HashSet 是不可以有重复元素的,那调用add()方法时,它的内部是怎么判断这个对象是否在该HashSet中存在的呢?比如: HashSet<Person> set = new HashSet<Person>(); Person p1 = new Person("tom", 12); Person p2 = new Person("tom", 12); set