Дублирование всех объектов в ArrayBag
В настоящее время я изучаю различные DataStructures в Java, одна из которых - Array Bags и Linked Bags. Я понимаю причину, по которой структуры данных так важны, и то, как дженерики позволяют нам легче обрабатывать объекты единообразным образом, независимо от их типа (если мое мышление или понимание этого утверждения неверно по причине использования структур данных, скажи пожалуйста).
С учетом вышесказанного, есть некоторые аспекты обобщений и структур данных, которые я не до конца понимаю. В этой ветке не упоминаются, в частности, такие, поскольку я буду продолжать искать эти вещи отдельно, но это может повлиять на то, почему у меня возникают проблемы с правильной реализацией метода, который позволит мне дублировать все элементы данной сумки.
Ниже приведен код лаборатории, над которой я работаю. Лаборатория просит, чтобы я выполнил определенные методы в этом файле, чтобы при компиляции и запуске драйвера соответствующие ответы возвращались в командную строку. Я считаю, что то, что я сделал до сих пор, правильно, когда я запускаю драйвер. Но когда я пытаюсь завершить 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
Когда я пытаюсь скомпилировать код, я получаю следующие ошибки:
./ArrayBag.java:260: error: cannot find symbol
if(!thisBag.isEmpty()){
^
symbol: method isEmpty()
location: variable thisBag of type T[]
where T is a type-variable:
T extends Object declared in class ArrayBag
./ArrayBag.java:263: error: cannot find symbol
success = thisBag.add(thisBag[index]);
^
symbol: method add(T)
location: variable thisBag of type T[]
where T is a type-variable:
T extends Object declared in class ArrayBag
2 errors
я пробовал 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
И я получаю следующую ошибку во время компиляции:
./ArrayBag.java:263: error: array required, but ArrayBag<T> found
success = this.add(this[index]);
^
where T is a type-variable:
T extends Object declared in class ArrayBag
1 error
Итак, я знаю, что так как я не бросил this
правильно, я получаю ошибку прямо выше. Но две ошибки, опубликованные выше последней, - это то, где я зацикливаюсь.
Мои вопросы:
Почему я получаю эти ошибки? Я получил похожие ошибки, касающиеся cannot find symbol
в моем последнем классе Java, и это было, когда я считаю, что я не был должным образом создан? Я думал, что мой подход был правильным, потому что я бросил T[] thisBag = this.toArray();
, а затем попытался использовать thisBag
и записи в коде в методе. Так как это неправильно, я не уверен, как очистить их generics
и ArrayBag/Bag DataStructures.
Кроме того, я подхожу к дублированию записей в общей сумке или есть лучший способ, о котором я не знаю? Я пытаюсь использовать add()
метод в этом файле в моих интересах, но у меня, очевидно, возникают трудности. Просматривая документацию по API Java в Интернете, я вижу, что для достижения этого дублирования можно воспользоваться несколькими путями:
arrays.fill
arrays.setAll(T[] array, IntFunction<? extends T> generator)
arrays.clone
Я думаю, что сначала мне нужно убедиться, что в массиве достаточно фиксированного пространства, чтобы дублировать его в памяти. Если нет, мне пришлось бы использовать динамический массив, удвоить пространство и дважды скопировать содержимое в новый массив. Это ново для меня и лично не вникал в этот тип подхода (только что изучил концепцию).
Как всегда, я с нетерпением жду возможности услышать, как вы все решите подобную проблему! А также скажите мне, что я делаю не так!
ЭТА: ДОБАВЛЕНИЕ ОТВЕТА, КОТОРЫЙ БЫЛ ПРЕДОСТАВЛЕН, И ДРУГОЙ ВОПРОС, ОПЫТНЫЙ С МОЕЙ ИСПРАВЛЕНИЕ
После того, как @gar предложил ниже, я реализовал следующее:
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
Когда я сделал это, я начал получать следующую ошибку:
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
строки, чтобы увидеть изменения размеров моих массивов при их дублировании и заметили, что первый массив (который содержал одну запись) заканчивался тремя записями. Я удалил numberOfEntries++;
с конца duplicateAll()
метод, и это исправило мою проблему.
Просто подумал, что я поделюсь этой информацией, чтобы другие знали.
Как всегда, отличная информация!
2 ответа
Вы путаетесь между методами вашего объекта и массива. Вы, кажется, довольно близко со второй попытки, которую вы предоставили. isEmpty
метод на вашем ArrayBag
класс в то время как [...]
аксессор только для массивов. Изменение фрагмента кода, чтобы получить запись для добавления из массива вместо объекта, будет выглядеть так:
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]);