2013-10-31 62 views
5

好吧,我有一個非常惱人的錯誤。它來自我的retainAll方法。問題是我最終輸出了1,3,5,但我需要1,3,5,7,9。以下是MySet和驅動程序類的代碼在我的「自定義設置」實施中需要幫助

public class MySetTester { 

    public static void main(String[]args) { 
     MySet<String> strings = new MySet<String>(); 
     strings.add("Hey!"); 
     strings.add("Hey!"); 
     strings.add("Hey!"); 
     strings.add("Hey!"); 
     strings.add("Hey!"); 
     strings.add("Listen!"); 
     strings.add("Listen!"); 
     strings.add("Sorry, I couldn't resist."); 
     strings.add("Sorry, I couldn't resist."); 
     strings.add("(you know you would if you could)"); 
     System.out.println("Testing add:\n"); 
     System.out.println("Your size: " + strings.size() 
         + ", contains(Sorry): " + strings.contains("Sorry, I couldn't resist.")); 
     System.out.println("Exp. size: 4, contains(Sorry): true\n"); 
     MySet<String> moreStrings = new MySet<String>(); 
     moreStrings.add("Sorry, I couldn't resist."); 
     moreStrings.add("(you know you would if you could)"); 
     strings.removeAll(moreStrings); 
     System.out.println("Testing remove and removeAll:\n"); 
     System.out.println("Your size: " + strings.size() 
          + ", contains(Sorry): " 
          + strings.contains("Sorry, I couldn't resist.")); 
     System.out.println("Exp. size: 2, contains(Sorry): false\n"); 


     MySet<Integer> ints = new MySet<Integer>(); 
     for (int i = 0; i < 100; i++) { 
      ints.add(i); 
     } 

     System.out.println("Your size: " + ints.size()); 
     System.out.println("Exp. size: 100\n"); 

     for (int i = 0; i < 100; i += 2) { 
      ints.remove(i); 
     } 

     System.out.println("Your size: " + ints.size()); 
     System.out.println("Exp. size: 50\n"); 
     MySet<Integer> zeroThroughNine = new MySet<Integer>(); 

     for (int i = 0; i < 10; i++) { 
      zeroThroughNine.add(i); 
     } 
     ints.retainAll(zeroThroughNine); 
     System.out.println("ints should now only retain odd numbers" 
          + " 0 through 10\n"); 

     System.out.println("Testing your iterator:\n"); 

     for (Integer i : ints) { 
      System.out.println(i); 
     } 

     System.out.println("\nExpected: \n\n1 \n3 \n5 \n7 \n9\n"); 

     System.out.println("Yours:"); 
     for (String s : strings) { 
      System.out.println(s); 
     } 
     System.out.println("\nExpected: \nHey! \nListen!"); 
     strings.clear(); 
     System.out.println("\nClearing your set...\n"); 
     System.out.println("Your set is empty: " + strings.isEmpty()); 
     System.out.println("Exp. set is empty: true"); 
    } 
} 

這裏是主代碼。但仍然閱讀最重要的部分,因爲這就是我的例子。

import java.util.Set; 
import java.util.Collection; 
import java.lang.Iterable; 
import java.util.Iterator; 
import java.util.Arrays; 
import java.lang.reflect.Array; 
public class MySet<E> implements Set<E>, Iterable<E> 
{ 
    // instance variables - replace the example below with your own 
    private E[] backingArray; 
    private int numElements; 

    /** 
    * Constructor for objects of class MySet 
    */ 
    public MySet() 
    { 
     backingArray=(E[]) new Object[5]; 
     numElements=0; 
    } 
    public boolean add(E e){ 

     for(Object elem:backingArray){ 
      if (elem==null ? e==null : elem.equals(e)){ 
       return false; 
      } 
     } 
     if(numElements==backingArray.length){ 
      E[] newArray=Arrays.copyOf(backingArray,backingArray.length*2); 
      newArray[numElements]=e; 
      numElements=numElements+1; 
      backingArray=newArray; 
      return true; 
     } 
     else{ 
      backingArray[numElements]=e; 
      numElements=numElements+1; 
      return true; 
     } 
    } 
    public boolean addAll(Collection<? extends E> c){ 
     for(E elem:c){ 
      this.add(elem); 
     } 
     return true; 
    } 
    public void clear(){ 
     E[] newArray=(E[])new Object[backingArray.length]; 
     numElements=0; 
     backingArray=newArray; 
    } 
    public boolean equals(Object o){ 
     if(o instanceof Set &&(((Set)o).size()==numElements)){ 
      for(E elem:(Set<E>)o){ 
       if (this.contains(o)==false){ 
       return false; 
      } 
      return true; 
      } 
     } 
     return false; 
    } 
    public boolean contains(Object o){ 
     for(E backingElem:backingArray){ 
        if (o!=null && o.equals(backingElem)){ 
         return true; 
        } 
       } 
     return false; 
    } 
    public boolean containsAll(Collection<?> c){ 
     for(E elem:(Set<E>)c){ 
      if(!(this.contains(elem))){ 
       return false; 
      } 
     } 
     return true; 
    } 
    public int hashCode(){ 
     int sum=0; 
     for(E elem:backingArray){ 
      if(elem!=null){ 
      sum=sum+elem.hashCode(); 
     } 
    } 
     return sum; 
    } 
    public boolean isEmpty(){ 
     if(numElements==0){ 
      return true; 
     } 
     else{ 
      return false; 
     } 
    } 
    public boolean remove(Object o){ 
     int i=0; 
     for(Object elem:backingArray){ 
      if(o!=null && o.equals(elem)){ 
       backingArray[i]=null; 
       numElements=numElements-1; 
       E[] newArray=Arrays.copyOf(backingArray,backingArray.length-1); 
       return true;    
      } 
      i=i+1; 
     } 
     return false; 
    } 
    public boolean removeAll(Collection<?> c){ 
     for(Object elem:c){ 
      this.remove(elem); 
     } 
     return true; 

    } 
    public boolean retainAll(Collection<?> c){ 
     MySet<E> removalArray=new MySet<E>(); 
     for(E arrayElem:backingArray){ 
      if(arrayElem!= null && !(c.contains(arrayElem))){ 
       this.remove(arrayElem); 
      } 
    } 
    return false; 
} 
    public int size(){ 
     return numElements; 
    } 
    public <T> T[] toArray(T[] a) throws ArrayStoreException,NullPointerException{ 
     for(int i=0;i<numElements;i++){ 
      a[i]=(T)backingArray[i]; 
     } 
     for(int j=numElements;j<a.length;j++){ 
      a[j]=null; 
     } 
     return a; 
    } 
    public Object[] toArray(){ 
     Object[] newArray=new Object[numElements]; 
     for(int i=0;i<numElements;i++){ 
      newArray[i]=backingArray[i]; 
     } 
     return newArray; 
    } 
    public Iterator<E> iterator(){ 
     setIterator iterator=new setIterator(); 
     return iterator; 
    } 
    private class setIterator implements Iterator<E>{ 
     private int currIndex; 
     private E lastElement; 
     public setIterator(){ 
      currIndex=0; 
      lastElement=null; 
     } 
     public boolean hasNext(){ 
      while(currIndex<=numElements && backingArray[currIndex]==null){ 
       currIndex=currIndex+1; 
      } 
      if (currIndex<=numElements){ 
       return true; 
      } 
      return false; 
     } 
     public E next(){ 
      E element=backingArray[currIndex]; 
      currIndex=currIndex+1; 
      lastElement=element; 
      return element; 
     } 
     public void remove() throws UnsupportedOperationException,IllegalStateException{ 
      if(lastElement!=null){ 
       MySet.this.remove((Object)lastElement); 
       numElements=numElements-1; 
      } 
      else{ 
      throw new IllegalStateException(); 
     } 
    } 
} 
} 

我已經能夠減少問題,但否則這件事仍然會造成問題。

+0

爲MYSET類代碼段缺少初始行做到這一點。請添加這些。 –

回答

4

remove方法中的錯誤。我添加了我的實現方法:

public boolean remove(Object o) { 
    int i = 0; 
    for (Object elem : backingArray) { 
     if (o != null && o.equals(elem)) { 
      System.arraycopy(backingArray, i+1, backingArray, i, numElements-i-1); 
      backingArray[numElements-1] = null; 
      numElements = numElements - 1; 
      return true; 
     } 
     i = i + 1; 
    } 
    return false; 
} 

和方法retainAll中的另一個錯誤。我添加了我的實現方法:

public boolean retainAll(Collection<?> c) { 
    int index = 0; 
    boolean result = false; 
    if (this.containsAll(c)){ 
     result = true; 
    } 

    while(index < numElements) { 
     E e = backingArray[index]; 
     if (e != null && !(c.contains(e))) { 
      this.remove(e); 
     } else { 
      index++; 
     } 
    } 
    return result; 
} 
0

問題已回答@frostjogla。再加一個。如果您每次檢查backingArray的實際內容,則可能會提前注意到該問題。

您可以通過覆蓋toString方法類似

@Override 
public String toString() { 
    StringBuilder sb = new StringBuilder(); 
    for (E backingElem : backingArray) { 
     sb.append(" ").append(backingElem); 
    } 
    return sb.toString(); 
} 

和打印由

System.out.println("Contents of MySet " + ints);