Java 复制ArrayBag中的所有对象
我目前正在学习Java中的不同数据结构,一种是数组包和链接包。我理解数据结构如此重要的原因,以及泛型如何使我们能够以统一的方式更轻松地处理对象,无论对象的类型如何(如果我对该语句的思考或理解由于使用数据结构背后的原因是错误的,请告诉我) 尽管如此,泛型和数据结构的某些方面我还没有完全理解。这个帖子并没有特别提到这些内容,因为我将继续单独查找这些内容,但它可能会影响我为什么在正确实现允许复制给定包的所有项目的方法时遇到问题 下面是我正在工作的一个实验室的代码。实验室要求我完成此文件中的某些方法,以便在编译和运行驱动程序时,将适当的答案返回到命令提示符。我相信,我到目前为止所做的是正确的,当我运行的驱动程序。但是,当我尝试完成Java 复制ArrayBag中的所有对象,java,arrays,generics,bag,Java,Arrays,Generics,Bag,我目前正在学习Java中的不同数据结构,一种是数组包和链接包。我理解数据结构如此重要的原因,以及泛型如何使我们能够以统一的方式更轻松地处理对象,无论对象的类型如何(如果我对该语句的思考或理解由于使用数据结构背后的原因是错误的,请告诉我) 尽管如此,泛型和数据结构的某些方面我还没有完全理解。这个帖子并没有特别提到这些内容,因为我将继续单独查找这些内容,但它可能会影响我为什么在正确实现允许复制给定包的所有项目的方法时遇到问题 下面是我正在工作的一个实验室的代码。实验室要求我完成此文件中的某些方法,以
duplicateAll()
方法(下面文件中倒数第二个方法)时,无论我如何尝试更改它,我都会继续遇到相同的错误。请记住,我的最后一个方法removeDuplicates()
还不完整,但我还不在实验室的这一部分
代码如下:
import java.util.Arrays;
import java.util.Random;
public final class ArrayBag<T> implements BagInterface<T> {
private final T[] bag;
private int numberOfEntries;
private static final int DEFAULT_CAPACITY = 25;
private boolean initialized = false;
private static final int MAX_CAPACITY = 10000;
/** Creates an empty bag whose initial capacity is 25. */
public ArrayBag() {
this(DEFAULT_CAPACITY);
} // end default constructor
/**
* Creates an empty bag having a given initial capacity.
*
* @param desiredCapacity The integer capacity desired.
*/
public ArrayBag(int desiredCapacity) {
if (desiredCapacity <= MAX_CAPACITY) {
// The cast is safe because the new array contains null entries.
@SuppressWarnings("unchecked")
T[] tempBag = (T[]) new Object[desiredCapacity]; // Unchecked cast
bag = tempBag;
numberOfEntries = 0;
initialized = true;
}
else
throw new IllegalStateException("Attempt to create a bag " +
"whose capacity exceeds " +
"allowed maximum.");
} // end constructor
/** Adds a new entry to this bag.
@param newEntry The object to be added as a new entry.
@return True if the addition is successful, or false if not. */
public boolean add(T newEntry) {
checkInitialization();
boolean result = true;
if (isArrayFull()) {
result = false;
} else { // Assertion: result is true here
bag[numberOfEntries] = newEntry;
numberOfEntries++;
} // end if
return result;
} // end add
/** Throws an exception if this object is not initialized.
*
*/
private void checkInitialization()
{
if (!initialized)
throw new SecurityException("ArrayBag object is not initialized " +
"properly.");
}
/** Retrieves all entries that are in this bag.
@return A newly allocated array of all the entries in the bag. */
public T[] toArray() {
// the cast is safe because the new array contains null entries
@SuppressWarnings("unchecked")
T[] result = (T[]) new Object[numberOfEntries]; // unchecked cast
for (int index = 0; index < numberOfEntries; index++) {
result[index] = bag[index];
} // end for
return result;
} // end toArray
/** Sees whether this bag is full.
@return True if the bag is full, or false if not. */
private boolean isArrayFull() {
return numberOfEntries >= bag.length;
} // end isArrayFull
/** Sees whether this bag is empty.
@return True if the bag is empty, or false if not. */
public boolean isEmpty() {
return numberOfEntries == 0;
} // end isEmpty
/** Gets the current number of entries in this bag.
@return The integer number of entries currently in the bag. */
public int getCurrentSize() {
return numberOfEntries;
} // end getCurrentSize
/** Counts the number of times a given entry appears in this bag.
@param anEntry The entry to be counted.
@return The number of times anEntry appears in the bag. */
public int getFrequencyOf(T anEntry) {
checkInitialization();
int counter = 0;
for (int index = 0; index < numberOfEntries; index++) {
if (anEntry.equals(bag[index])) {
counter++;
} // end if
} // end for
return counter;
} // end getFrequencyOf
/** Tests whether this bag contains a given entry.
@param anEntry The entry to locate.
@return True if the bag contains anEntry, or false if not. */
public boolean contains(T anEntry) {
checkInitialization();
return getIndexOf(anEntry) > -1;
} // end contains
/** Removes all entries from this bag. */
public void clear() {
while (!isEmpty()) {
remove();
}
} // end clear
/** Removes one unspecified entry from this bag, if possible.
@return Either the removed entry, if the removal was successful,
or null if otherwise. */
public T remove() {
checkInitialization();
// MODIFY THIS METHOD TO REMOVE A RANDOM ITEM FROM THE BAG
Random randomNum = new Random();
if(numberOfEntries > 0){
int randomKey = randomNum.nextInt(numberOfEntries);
T result = removeEntry(randomKey);
return result;
}else{
return null;
}
} // end remove
/** Removes one occurrence of a given entry from this bag.
@param anEntry The entry to be removed.
@return True if the removal was successful, or false if not. */
public boolean remove(T anEntry) {
checkInitialization();
int index = getIndexOf(anEntry);
T result = removeEntry(index);
return anEntry.equals(result);
} // end remove
// Removes and returns the entry at a given array index within the array bag.
// If no such entry exists, returns null.
// Preconditions: 0 <= givenIndex < numberOfEntries;
// checkInitialization has been called.
private T removeEntry(int givenIndex) {
T result = null;
if (!isEmpty() && (givenIndex >= 0)) {
result = bag[givenIndex]; // entry to remove
bag[givenIndex] = bag[numberOfEntries - 1]; // Replace entry with last entry
bag[numberOfEntries - 1] = null; // remove last entry
numberOfEntries--;
} // end if
return result;
} // end removeEntry
// Locates a given entry within the array bag.
// Returns the index of the entry, if located, or -1 otherwise.
// Precondition: checkInitialization has been called.
private int getIndexOf(T anEntry) {
int where = -1;
boolean stillLooking = true;
int index = 0;
while ( stillLooking && (index < numberOfEntries)) {
if (anEntry.equals(bag[index])) {
stillLooking = false;
where = index;
} // end if
index++;
} // end for
// Assertion: If where > -1, anEntry is in the array bag, and it
// equals bag[where]; otherwise, anEntry is not in the array
return where;
} // end getIndexOf
/** Override the equals method so that we can tell if two bags contain the same items
* the contents in the bag.
* @return a string representation of the contents of the bag */
public String toString() {
String result = "Bag{Size:" + numberOfEntries + " ";
for (int index = 0; index < numberOfEntries; index++) {
result += "[" + bag[index] + "] ";
} // end for
result += "}";
return result;
} // end toArray
/*********************************************************************
*
* METHODS TO BE COMPLETED
*
*
************************************************************************/
/** Check to see if two bags are equals.
* @param aBag Another object to check this bag against.
* @return True the two bags contain the same objects with the same frequencies.
*/
public boolean equals(ArrayBag<T> aBag) {
boolean result = false; // result of comparison of bags
boolean sameLength = false;
T[] thisBag = this.toArray();
T[] otherBag = aBag.toArray();
Arrays.sort(thisBag);
Arrays.sort(otherBag);
if (thisBag.length == otherBag.length){
sameLength = true;
}
if(sameLength){
for(int index = 0; index < otherBag.length; index++)
{
if(thisBag[index].equals(otherBag[index])){
result = true;
}
}
}
return result;
} // end equals
/** Duplicate all the items in a bag.
* @return True if the duplication is possible.
*/
public boolean duplicateAll() {
checkInitialization();
boolean success = false;
T[] thisBag = this.toArray();
if(!thisBag.isEmpty()){
int originalTotalEntries = numberOfEntries;
for(int index = 0; index < originalTotalEntries; index++){
success = thisBag.add(thisBag[index]);
numberOfEntries++;
}
}
return success;
} // end duplicateAll
/** Remove all duplicate items from a bag
*/
public void removeDuplicates() {
checkInitialization();
// COMPLETE THIS METHOD
return;
} // end removeDuplicates
} // end ArrayBag
我尝试了this.
代替thisBag
如下(仅粘贴duplicateAll()
方法:
public boolean duplicateAll() {
checkInitialization();
boolean success = false;
T[] thisBag = this.toArray(); //not needed anymore
if(!this.isEmpty()){
int originalTotalEntries = this.numberOfEntries;
for(int index = 0; index < originalTotalEntries; index++){
success = this.add(this[index]);
numberOfEntries++;
}
}
return success;
} // end duplicateAll
当我这样做时,我开始收到以下错误:
Exception in thread "main" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:325)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
at java.util.Arrays.sort(Arrays.java:1246)
at ArrayBag.equals(ArrayBag.java:234)
at BagExtensionsTest.checkDuplicateAll(BagExtensionsTest.java:720)
at BagExtensionsTest.main(BagExtensionsTest.java:52)
我在这个网站上做了一些挖掘,读到这是由数组中的null
条目引起的(因此java.lang.NullPointerException
。添加了一些System.out.println
行,以查看复制数组时数组大小的变化,并注意到第一个数组(包含一个条目)以三个条目结束。我从duplicateAll()
方法的末尾删除了numberOfEntries++;
,它纠正了我的问题
我只是想和别人分享这些信息
像往常一样,信息非常好!您正在混淆对象和数组上的方法。您提供的第二次尝试似乎非常接近。
isEmpty
方法位于ArrayBag
类上,而[…]
accessor仅适用于数组。修改代码段以从数组而不是对象中获取要添加的条目,如下所示:
public boolean duplicateAll() {
checkInitialization();
boolean success = false;
T[] thisBag = this.toArray(); //not needed anymore
if(!this.isEmpty()){
int originalTotalEntries = this.numberOfEntries;
for(int index = 0; index < originalTotalEntries; index++){
success = this.add(thisBag[index]);
numberOfEntries++;
}
}
return success;
} // end duplicateAll
public boolean duplicateAll(){
检查初始化();
布尔成功=假;
T[]thisBag=this.toArray();//不再需要
如果(!this.isEmpty()){
int originalTotalEntries=this.numberOfEntries;
对于(int index=0;index
我尚未对此进行测试,因此可能存在其他错误,但希望它能让您在这条道路上走得更远。尝试替换此:
if(!thisBag.isEmpty()){
致:
以及:
success = this.add(this[index]);
致:
你的建议奏效了。我发现我必须删除
numberOfEntries++;
,因为我一直在接收NullPointerExceptions
。经过一些挖掘,我注意到它正在将null
添加到数组中。一旦我删除了它,一切都正常进行了。干得好,建议多多!
public boolean duplicateAll() {
checkInitialization();
boolean success = false;
T[] thisBag = this.toArray(); //not needed anymore
if(!this.isEmpty()){
int originalTotalEntries = this.numberOfEntries;
for(int index = 0; index < originalTotalEntries; index++){
success = this.add(thisBag[index]);
numberOfEntries++;
}
}
return success;
} // end duplicateAll
if(!thisBag.isEmpty()){
if(thisBag.length>0){
success = this.add(this[index]);
success = this.add(thisBag[index]);