实现equals()方法来比较两个'bag'对象的内容

时间:2016-02-14 05:16:01

标签: java arrays object clone equals

我正在完成一项学校作业。目标是练习GUI,clone()方法,以及使用/修改现有代码。 我试图以教师的方式编写一个equals方法 - 通过使用对象的克隆,从包中删除项目(根据成功或失败的方式返回布尔值)。

包以数组表示,在{1,2,3}和{3,2,1}等情况下应该返回true,即顺序无关紧要,只有每个数字的数量在阵列。

以下是问题

它适用于大多数情况,但是如果行李包含数字,则会出现错误:{1,1,2}和{1,2,2}以及其他类似的迭代。它返回true而不是false。

我认为它与我们应该使用的remove()方法有关。如果我理解正确,它应该将值放在数组的'end'并减少manyItems计数器(这是数组中项目数的变量,因为array.length默认情况下在构造函数10中。)

代码主要由另一个人编写。我们必须导入现有文件并编写新方法来完成我们给出的任务。我已完成所有GUI部分,因此我不会包含该类,只包含IntArrayBag类中使用的方法。

第二双眼睛会有所帮助。感谢。

public class IntArrayBag implements Cloneable
{
// Invariant of the IntArrayBag class:
//   1. The number of elements in the bag is in the instance variable 
//      manyItems, which is no more than data.length.
//   2. For an empty bag, we do not care what is stored in any of data;
//      for a non-empty bag, the elements in the bag are stored in data[0]
//      through data[manyItems-1], and we don�t care what�s in the
//      rest of data.
private int[ ] data;
private int manyItems;

public IntArrayBag( )
{
  final int INITIAL_CAPACITY = 10;
  manyItems = 0;
  data = new int[INITIAL_CAPACITY];
}

public IntArrayBag clone( )
{  // Clone an IntArrayBag object.
  IntArrayBag answer;

  try
  {
     answer = (IntArrayBag) super.clone( );
  }
  catch (CloneNotSupportedException e)
  {  // This exception should not occur. But if it does, it would probably
     // indicate a programming error that made super.clone unavailable.
     // The most common error would be forgetting the "Implements Cloneable"
     // clause at the start of this class.
     throw new RuntimeException
     ("This class does not implement Cloneable");
  }

  answer.data = data.clone( );

  return answer;
}

public int size( )
{
  return manyItems;
}

public boolean remove(int target)
{
  int index; // The location of target in the data array.

  // First, set index to the location of target in the data array,
  // which could be as small as 0 or as large as manyItems-1; If target
  // is not in the array, then index will be set equal to manyItems;
  for (index = 0; (index < manyItems) && (target != data[index]); index++)
     // No work is needed in the body of this for-loop.
     ;

  if (index == manyItems)
     // The target was not found, so nothing is removed.
     return false;
  else
  {  // The target was found at data[index].
     // So reduce manyItems by 1 and copy the last element onto data[index].
     manyItems--;
     data[index] = data[manyItems];
     return true;
  }
}
//I added extra variables that are not needed to try to increase readability,
//as well as when i was trying to debug the code originally
public boolean equals(Object obj){

   if (obj instanceof IntArrayBag){

       IntArrayBag canidate = (IntArrayBag) obj; // i know this can be changed, this was required
       IntArrayBag canidateTest = (IntArrayBag) canidate.clone(); //this was created
       //as a clone because it was otherwise referring to the same memory address
       //this caused items to be removed from bags when testing for equality
       IntArrayBag test = (IntArrayBag) this.clone();

       //fast check to see if the two objects have the same number of items, 
       //if they dont will return false and skip the item by item checking
       if (test.size() != canidateTest.size())
           return false;

       //the loop will go through every element in the test bag it will 
       //then remove the value that is present at the first index of the test bag
       for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){
           int check = test.data[i];
           //remove() returns a boolean so if the value is not present in each bag
           //then the conditional will be met and the method will return false
           boolean test1 = test.remove(check);
           boolean test2 = canidateTest.remove(check);
           if (test1 != test2)
               return false;

       }//end for loop

       // if the loop goes through every element
       //and finds every value was true it will return true
       return true;  
   }//end if 
   else
       return false;
}//end equals
}

4 个答案:

答案 0 :(得分:1)

是否明确声明使用克隆?您可以通过覆盖此对象的hashCode()来轻松实现。

您可以按如下方式覆盖此对象的hashCode()

@Override
public int hashCode() {
    final int prime = 5;
    int result = 1;
    /* Sort Array */
    Arrays.sort(this.data);
    /* Calculate Hash */
    for(int d : this.data) {
        result = prime * result + d;
    }
    /* Return Result */
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || this.getClass() != obj.getClass()){
            return false;
    }
    return false;
}

如果您想继续使用等于testCandidateTest的等号实现,那么您还可以计算唯一的哈希值并根据结果做出决定。

以下是代码段:

/* Assuming that you have put size comparison logic on top 
   and the two objects are of same size */

final int prime = 31;
int testResult = 1;
int candidateTestResult = 1;
for(int i = 0; i < test.size(); i++) {
    testResult = prime * testResult + test.data[i];
    candidateTestResult = prime * candidateTestResult + candidateTest.data[i];
}
/* Return Result */
return testResult == candidateTestResult;

答案 1 :(得分:1)

我无法看到全局,因为我之前没有使用Java编写GUI,但是,就比较2个int []数组而言,我会在比较之前对数组进行排序。这将允许您消除问题案例,如您所述的问题(如果可以排序),然后应用类似:

while(array_1[index]==array_2[index] && index<array_1.length)
{index++;}

通过检查索引的最终值

找到循环中断的位置

答案 2 :(得分:0)

我认为问题出在这一行:

for (int i = 0; (i < (test.size()) || i < (canidateTest.size())); i++){

这里的问题是testcanidateTest是您制作的克隆,并且您要从这些包中删除元素。每当您从包中删除元素时,size都会减少(因为您减少manyItemssize()会返回manyItems)。这意味着您只需要通过一半的阵列。假设原始大小为4.然后,第一次循环,i==0test.size()==4;第二次,i==0test.size()==3;第三次,i==2test.size()==2,然后退出循环。所以你不要看所有4个元素 - 你只看2。

您需要决定:您是否想要浏览原始数组的元素或克隆的元素?如果您浏览克隆的元素,实际上您永远不需要增加i。您可以随时查看test.data[0],因为一旦您查看它,就会将其删除,因此您知道test.data[0]将替换为其他内容。事实上,您根本不需要i。只需循环直到袋子尺寸为0,或直到您确定袋子不相等为止。另一方面,如果您浏览this.data的元素(即查看this.data[i]data[i]),请确保i一直到this.size() {1}}。

(还有一点:正确的拼写是&#34;候选人&#34;。)

答案 3 :(得分:-1)

也许你应该尝试SET界面 详细查看:http://www.tutorialspoint.com/java/java_set_interface.htm set对象不能包含重复元素,因此它适合您的作业,而不是构建自己的类。

例如:[1,1,2]和[1,2,2] 你可以用它来测试它们是否相等

arr1 = {1,1,2}
arr2 = {1,2,2}
Set<Integer> set = new HashSet<Integer>();
for(int i : arr1){//build set of arr1
    if(set.contains(i)==false){
        set.add(i)
    }
}
for(int i:arr2){
    if(set.contains(i)==false){
        System.out.println('not equal');
        break;
    }
}

希望这有用。