我正在完成一项学校作业。目标是练习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
}
答案 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;
}
如果您想继续使用等于test
和CandidateTest
的等号实现,那么您还可以计算唯一的哈希值并根据结果做出决定。
以下是代码段:
/* 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++){
这里的问题是test
和canidateTest
是您制作的克隆,并且您要从这些包中删除元素。每当您从包中删除元素时,size
都会减少(因为您减少manyItems
,size()
会返回manyItems
)。这意味着您只需要通过一半的阵列。假设原始大小为4.然后,第一次循环,i==0
和test.size()==4
;第二次,i==0
和test.size()==3
;第三次,i==2
和test.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;
}
}
希望这有用。