我的Intset班有什么不对吗?

时间:2010-08-29 09:59:40

标签: java

我设计了使用ArrayList的新IntSet类。首先,我通过ArrayList扩展Intset,然后启动实现方法。我在union()方法中遇到了一些问题。这是我的代码......

public class IntSet extends ArrayList<Integer>{

    private static final long serialVersionUID = 1L;
    private ArrayList<Integer> intset;

    public IntSet(){
        this.intset = new ArrayList<Integer>();
    }
    public IntSet(ArrayList<Integer> intset){
        this.intset = intset;
    }

    public void insert(int x){
        this.intset.add(x);
    }

    @Override
    public Integer remove(int x){
        int index = intset.indexOf(x);
        this.intset.remove(index);
        return 1;
    }

    @Override
    public int size(){
        return this.intset.size();
    }

    @Override
    public Integer get(int index){
        return this.intset.get(index);
    }

    public boolean member(int x){
        if(intset.indexOf(x)==-1) return false;
        else return true;
    }

    public IntSet union(IntSet a){
        IntSet intersectSet = new IntSet();
        intersectSet.insert(0);
        intersectSet.insert(1);
        System.out.println(intersectSet.size());
        System.out.println(intersectSet.contains(1));
        for(int i=0; i<a.size(); i++){
        }
        return intersectSet;
    }

    public String toString(){
        if(intset.size()==0) return "[]";
        String s = "[" + intset.get(0).toString();
        for(int i=1; i<intset.size(); i++){
            s += "," + intset.get(i).toString();
        }
        return s += "]";
    }

}

方法

union(IntSet a);

我构造新的Intset对象,然后将2个值(0,1)添加到 intersectSet 变量中。

intersectSet.insert(0);
intersectSet.insert(1);

然后我打印 intersectSet 的大小它显示我2正确!

但是当我需要检查 intersectSet 中是否有1?它让我觉得不对。

System.out.println(intersectSet.contains(1));

实际上它应该显示我是真的,因为在 intersectSet 中有整数1。

我的代码有什么问题,我应该为IntSet类扩展ArrayList吗?

4 个答案:

答案 0 :(得分:2)

关于班级设计的一些建议:

  • 没有你的类扩展ArrayList。 “set”真的不应该扩展List。但是,您应该实现Set。这将为编译器提供额外的好处,告诉您需要为集合实现哪些方法.....
  • 为了获得最快的性能(但需要更多工作!),您可能需要使用内部数组而不是ArrayList。
  • 考虑使结构不可变,使用返回新副本的函数而不是改变集合。根据您的使用情况,这可能是一个更好的解决方案,特别是如果您主要处理小型,不变的设置。
  • 同样取决于您的用法,您可能希望覆盖hashCode和equals以实现基于值的相等
  • 使用ArrayList构造Intset时,理想情况下应该防御性地复制(克隆)ArrayList。如果有人改变了原始的ArrayList,你不希望你设置改变。

答案 1 :(得分:1)

这里的问题是你实际上有2个ArrayLists。 IntSet类是一个ArrayList,但此类包含第二个ArrayList intset。摆脱其中一个ArrayLists。为了证明这一点,请添加第二行:

System.out.println(intersectSet.contains(1));
System.out.println(intersectSet.intset.contains(1));

这将输出:

false
true

所以你必须做出选择,我是从ArrayList继承还是包含ArrayList。当然,我在这里得到的是Effective Java的第16项,Favor composition over inheritance

答案 2 :(得分:0)

您正在扩展ArrayList并管理您自己的内部ArrayList对象,这意味着对于您已覆盖的所有方法,您正在与intset成员变量进行交互,否则您将与使用的继承内部表示进行交互由ArrayList超类。如果您覆盖contains方法,您将获得正确的行为。

我建议您删除ArrayList的子类,而是实现ListSet接口,但这取决于您被要求解决的确切问题。

答案 3 :(得分:0)

您需要覆盖contains方法。

public boolean contains(Object o) {
    return intset.contains(o);
    }

以及与其元素相关的其余ArrayList方法。

我觉得这不是一个好的解决方案。你可以尝试更好的方法。