import java.util.Iterator;
public class MyArrayList<E> implements Iterable<E> {
public static final int DEFAULT_SIZE = 5;
public static final int EXPANSION = 5;
private int capacity;
private int size;
private Object[] items;
public MyArrayList() {
size = 0;
capacity = DEFAULT_SIZE;
items = new Object[DEFAULT_SIZE];
}
private void expand() {
Object[] newItems = new Object[capacity + EXPANSION];
for (int j = 0; j < size; j++) newItems[j] = items[j];
items = newItems;
capacity = capacity + EXPANSION;
}
public void add(Object obj) {
if (size >= capacity) this.expand();
items[size] = obj;
size++;
}
public int size() {
return size;
}
public Object get(int index) {
try{
return items[index];
} catch(IndexOutOfBoundsException e){
System.out.println("Exception Thrown: " + "Index is out of bound");
}
return index;
}
public boolean contains(Object obj) {
for (int j = 0; j < size; j++) {
if (obj.equals(this.get(j))) return true;
}
return false;
}
public void add(int index, Object obj) {
try{
if (size >= capacity) this.expand();
for (int j = size; j > index; j--) items[j] = items[j - 1];
items[index] = obj;
size++;
} catch(IndexOutOfBoundsException e){
System.out.println("Exception Thrown: " + "Index is out of bound");
}
return;
}
public int indexOf(Object obj) {
for (int j = 0; j < size; j++) {
if (obj.equals(this.get(j))) return j;
}
return -1;
}
public boolean remove(Object obj) {
for (int j = 0; j < size; j++) {
if (obj.equals(this.get(j))) {
for (int k = j; k < size-1; k++) items[k] = items[k + 1];
size--;
items[size] = null;
return true;
}
}
return false;
}
public Object remove(int index) {
try{
Object result = this.get(index);
for (int k = index; k < size-1; k++) items[k] = items[k + 1];
items[size] = null;
size--;
return result;
} catch(IndexOutOfBoundsException e){
System.out.println("Exception Thrown: " + "Index is out of bound");
}
return index;
}
public void set(int index, Object obj) {
try{
items[index] = obj;
} catch(IndexOutOfBoundsException e){
System.out.println("Exception Thrown: " + "Index is out of bound");
}
return;
}
public Iterator<E> iterator() {
return new MyIterator<E>();
}
public class MyIterator <T> implements Iterator<T>{
public boolean hasNext(){
}
public T next(){
}
public void remove(){
}
}
}
Basically I'm trying to improve the functionality of my arraylist, as it uses for loops for methods such as add and remove, however I am trying to use an iterator instead and I searched it up and I found out you cannot just simply add implements iterable to the main class, it has to be implemented by using three methods next(), hasNext() and remove(). I added the three methods at the bottom of the code but i'm really not sure how I implement it in order for it to begin to work.
You'll need to keep track of the index in the items array that the Iterator is on. Let's call it int currentIndex. hasNext() will return true if currentIndex < size. next() will increment currentIndex if hasNext() is true and return items[currentIndex], otherwise it should throw an Exception, say NoSuchElementException. Remove will call remove(currentIndex).
Here is an example (NOTE: I have not tried to compile this or anything so please update this post if you find any errors!)
public class MyArrayList<E> implements Iterable<E> {
...
#Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private Object[] currentData = items;
private int pos = 0;
#Override
public boolean hasNext() {
return pos < currentData.length;
}
#Override
public E next() {
return (E) currentData[pos++];
}
#Override
public void remove() {
MyArrayList.this.remove(pos++);
}
};
}
}
You need to pass the items array to your MyIterator class so that you can keep track of the current position of the cursor in the array. Now based on the current position of the cursor you could implement all the abstract methods.
In the constructor of the MyIterator class pass the array as a parameter as public MyIterator(E[] array) and store the array as a local variable. also create a local variable cursor and set its value to 0.
Related
I've been trying to turn this generic arraylist class into an array but I haven't been able to get it to work. I've hit a roadblock at the push() and pop() methods. Any help is appreciated.
Here's the original class:
public class GenericStack<E> {
private java.util.ArrayList<E> list = new java.util.ArrayList<E>();
public int getSize() {
return list.size();
}
public E peek() {
return list.get(getSize() - 1);
}
public E push(E o) {
list.add(o);
return o;
}
public E pop() {
E o = list.get(getSize() - 1);
list.remove(getSize() - 1);
return o;
}
public boolean isEmpty() {
return list.isEmpty();
}
}
And here's my revised class so far:
public class GenericStack<E> {
public static int size = 16;
#SuppressWarnings("unchecked")
private E[] list = (E[])new Object[size];
public void add(int index, E e) {
ensureCapacity();
for (int i = size - 1; i >= index; i--) {
list[i + 1] = list[i];
list[index] = e;
size++;
}
}
public int getLength() {
return list.length;
}
public E peek() {
E o = null;
o = list[0];
return o;
}
public E push(E o) {
ensureCapacity();
list.append(o);
size++;
return o;
}
public E pop() {
E o = null;
for (int i = 0; i > list.length; i++) {
o = list[i - 1];
}
list[list.length - 1] = null;
size--;
return o;
}
private void ensureCapacity() {
if (size >= list.length) {
#SuppressWarnings("unchecked")
E[] newlist = (E[])(new Object[size * 2 + 1]);
System.arraycopy(list, 0, newlist, 0, size);
list = newlist;
}
}
public boolean isEmpty() {
if (list.length > 0) {
return false;
}
else {
return true;
}
}
}
NB: You must first correct your code like mentioned in comments.
It's recommended to use name method like of official Stack class, so there are 5 methods: empty() peek() pop() push(E item) search(Object o).
You should declare initial size of your array as a constant and an other variable for current size and all your attributes should be private like that:
private final int MAX_SIZE = 16;
private int currentSize=0;
There is the code of peek() method:
public E peek() {
E o = null;
o = list[currentSize-1];
return o;
}
There is the code of push(E o) method:
public E push(E o) {
list[currentSize]=o;
currentSize++;
return o;
}
There is the code of pop() method this method must throw EmptyStackException - if this stack is empty:
public E pop() {
E o = null;
if(currentSize>0){
o=list[currentSize - 1];
list[currentSize - 1] = null;
currentSize--;
return o;
}else{
throw new EmptyStackException();
}
}
There is the code of empty() method:
public boolean empty() {
if (currentSize > 0) {
return false;
}
else {
return true;
}
}
I am working with the code below. The list interface specifies two overloaded remove() methods. I cannot figure out how to determine which one Java uses if we invoke remove(3) on a List. How can we force Java to use the other one?
public class ArrayList<E> implements List1<E> {
private E[] data;
private int size;
public ArrayList(){
data = (E[]) (new Object[1]);
size = 0;
}
public void add(E target) {
if (isFull()) {
stretch();
}
data[size] = target;
size++;
}
public boolean isEmpty() {
return size == 0;
}
protected boolean isFull() {
return size == data.length;
}
public E get(int index) {
return data[index];
}
public void set(int index, E target) {
data[index] = target;
}
public int size() {
return size;
}
protected void stretch() {
E[] newData = (E[]) (new Object[data.length * 2]);
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
}
public boolean contains(E target) {
for (int i = 0; i < size; i++) {
if (data[i].equals(target)) {
return true;
}
}
return false;
}
public String toString() {
String result = "[";
for (int i = 0; i < size; i++) {
result += data[i] + "";
}
return result + "]";
}
public E remove(int index) {
E result = data[index];
for (int i = index; i < size; i++) {
data[i - 1] = data[i];
}
size--;
return result;
}
public boolean remove(E target) {
for (int i = 0; i < size; i++) {
if (data[i].equals(target)){
}
size--;
return true;
}
return false;
}
public static interface List1<E> {
public void add(E target);
public boolean contains(E traget);
public E get(int index);
public boolean isEmpty();
public E remove(int index);
public boolean remove(E index);
public void set(int index, E target);
public int size();
}
}
You have two remove() functions with different return data types and different function overloading data types. So Java would be able to distinguish those functions based on these parameters and thus will choose the appropriate function of your call. You cannot just force Java to use the other one, unless you want to call it explicitly from the first one as follows:
remove(datatype1 var1) {
remove(var2); //datatype2 of var2
//your code
}
remove(datatype2 var) {
//your code
}
If you see these two remove methods it's very clear that one take index of object in list while other take Object to delete. And the object is the Object of the Type of list. So if you want to use other one simply pass the object which is being contained by arrayList. For example:
If your list contains Integers:
List<Foo> integerList = new ArrayList<Foo>();
Foo foo = new Foo();
Foo foo1 = new Foo();
integerList.add(foo);
integerList.add(foo1);
integerList.remove(foo);//remove 1
integerList.remove(0);//remove 2
In above remove1 call the method remove(E target) will get called, on the other hand at remove 2 call the method remove(int index) will get called.
The assignment reads:
Give a complete implementation of a priority queue using an array of ordinary queues. For your ordinary queue, use the version...on page 402.
Pg402 reads:
public class PriorityQueue<E>
{
private ArrayQueue<E>[] queues;
...
In this implementation, the constructor allocates the memory for the array of queues with the statement:
queues = (ArrayQueue<E>[]) new Object[highest+1];
However:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lpriorityqueue.Queue;
at priorityqueue.PriorityQueue.(PriorityQueue.java:17)
at priorityqueue.PriorityQueue.main(PriorityQueue.java:67)
Java Result: 1
Exception on data = (Queue<T>[]) new Object[highPriority];
public class PriorityQueue<T>
{
private Queue<T>[] data;
private int size, hprior;
#SuppressWarnings("unchecked")
public PriorityQueue(int highPriority)
{
if(highPriority < 1)
throw new RuntimeException("Invalid priority number!");
data = (Queue<T>[]) new Object[highPriority]; //Error line 17
for(int i = 0; i < highPriority; i++)
{
data[i] = new Queue<>();
}
size = 0;
}
public void add(int priority, T element)
{
if(priority > data.length)
throw new RuntimeException("Invalid priority number!");
data[priority-1].enqueue(element);
size++;
}
public T remove()
{
if(empty())
throw new RuntimeException("Priority Queue is Empty!");
T element = null;
for(int i = data.length; i < 0; i--)
{
if(data[i].size()!=0)
element = (T) data[i].dequeue();
break;
}
return element;
}
public int size()
{
return size;
}
public boolean empty()
{
return size == 0;
}
public static void main(String[] args)
{
PriorityQueue<String> pq = new PriorityQueue<>(10); //Error at line 67
pq.add(1, "hi");
pq.add(2, "there!");
System.out.println(pq.remove());
}
}
class Queue<T>
{
private int front, rear, size;
public final static int DEFAULT_CAPACITY = 64;
private T[] queue;
public Queue(int capacity)
{
queue = (T[]) new Object[capacity];
size = 0;
front = 0;
rear = 0;
}
public Queue()
{
this(DEFAULT_CAPACITY);
}
public void enqueue(T element)
{
if(size() == queue.length)
throw new RuntimeException("Queue Full!");
queue[rear]= element;
rear = (rear +1) % queue.length;
size++;
}
public T dequeue()
{
if(empty())
throw new RuntimeException("Queue empty!");
T element = queue[front];
front = (front +1) % queue.length;
size--;
return element;
}
public int size()
{
return size;
}
public T front()
{
return queue[front];
}
public boolean empty()
{
return size == 0;
}
}
You can't randomly cast Object to some other type. If you want a Queue<T>[], you need to actually construct one. You can't really create an array with generics, so you're going to have to do something like this:
Queue<T>[] queue = (Queue<T> []) new ArrayDeque[10]; //or whatever concrete implementation you want.
Okay I have a really annoying error. Its coming from my retainAll method. The problem is that I am outputting 1,3,5 in ints at the end, but I need 1,3,5,7,9. Here is the code below for the MySet and driver classes
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");
}
}
And here is the main code. But still read the top part because that's where my examples are.
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();
}
}
}
}
I've been able to reduce the problems, but otherwise this thing is still causing problems.
Bug in the remove method. I added my implementation this method:
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;
}
and another bug in method retainAll. I added my implementation this method:
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;
}
Question is answered #frostjogla. Adding one more. If you've checked the actual content of backingArray each time, you could have noticed the issue earlier.
You can do it by overwriting the toString method like
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (E backingElem : backingArray) {
sb.append(" ").append(backingElem);
}
return sb.toString();
}
and print by
System.out.println("Contents of MySet " + ints);
I have three classes, those being Lister, ObjectSortedList and SortedListProgram. I'm having trouble with the iterator for the generic class. What am I doing wrong?
This is the error I get:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at objectsortedlist.ObjectSortedList.getData(ObjectSortedList.java:122)
at objectsortedlist.Lister.hasNext(Lister.java:28)
at objectsortedlist.SortedListProgram.main(SortedListProgram.java:52)
Java Result: 1
Here are my classes:
package objectsortedlist;
import java.util.Iterator;
/**
*
* #author Steven
*/
public class ObjectSortedList<T> implements Cloneable, Iterable<T> {
private T[] data;
private int capacity;
public ObjectSortedList()
{
final int init_capacity = 10;
capacity = 0;
data = (T[])new Object[init_capacity];
}
public ObjectSortedList(int init_capacity)
{
if(init_capacity < 0)
throw new IllegalArgumentException("Initial capacity is negative: " + init_capacity);
capacity = 0;
data = (T[])new Object[init_capacity];
}
private boolean empty()
{
if(data.length == 0 || data[0] == null)
return true;
else
return false;
}
public int length()
{
return capacity;
}
public void insert(T element)
{
if(capacity == data.length)
{
ensureCapacity(capacity * 2 + 1);
}
data[capacity] = element;
capacity++;
}
public boolean delete(T target)
{
int index;
if(target == null)
{
index = 0;
while((index < capacity) && (data[index] != null))
index++;
}
else
{
index = 0;
while((index < capacity) && (!target.equals(data[index])))
index++;
}
if(index == capacity)
return false;
else
{
capacity--;
data[index] = data[capacity];
data[capacity] = null;
return true;
}
}
private void ensureCapacity(int minCapacity)
{
T[] placeholder;
if(data.length < minCapacity)
{
placeholder = (T[])new Object[minCapacity];
System.arraycopy(data, 0, placeholder, 0, capacity);
data = placeholder;
}
}
public ObjectSortedList<T> clone()
{
// Cloning
ObjectSortedList<T> answer;
try
{
answer = (ObjectSortedList<T>) super.clone();
}
catch(CloneNotSupportedException cnse)
{
throw new RuntimeException("This class does not implement cloneable.");
}
answer.data = data.clone();
return answer;
}
#Override
public Iterator<T> iterator()
{
return (Iterator<T>) new Lister<T>(this, 0);
}
public T getData(int index)
{
return (T)data[index];
}
}
package objectsortedlist;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
*
* #author Steven
*/
public class Lister<T> implements Iterator<T>
{
private ObjectSortedList<T> current;
private int index;
public Lister(ObjectSortedList<T> top, int index)
{
current = top;
this.index = index;
}
#Override
public boolean hasNext()
{
return (current.getData(index) == null);
}
#Override
public T next()
{
T answer;
if(!hasNext())
throw new NoSuchElementException("The Lister is empty.");
answer = current.getData(index+1);
return answer;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Don't use this. Use objectsortedlist.SortedList.delete(T target).");
}
}
package objectsortedlist;
import java.util.Scanner;
/**
*
* #author Steven
*/
public class SortedListProgram {
private static Scanner scan = new Scanner(System.in);
private static String[] phraseArray = {"Hullabaloo!", "Jiggery pokery!", "Fantastic!", "Brilliant!", "Clever!", "Geronimo!", "Fish sticks and custard.", "Spoilers!",
"Exterminate!", "Delete!", "Wibbly-wobbly!", "Timey-wimey!"};
private static Lister<String> print;
public static void main(String args[])
{
int phraseNo = 0;
System.out.println("I'm gonna say some things at you, and you're going to like it."
+ " How many things would you like me to say to you? Put in an integer from 1-12, please.");
try
{
phraseNo = Integer.parseInt(scan.nextLine());
while((phraseNo < 1) || (phraseNo > 12))
{
System.out.println("The integer you entered wasn't between 1 and 12. Make it in between those numbers. Please? Pleaseeeee?");
phraseNo = Integer.parseInt(scan.nextLine());
}
}
catch(NumberFormatException nfe)
{
System.out.println("C'mon, why don't you follow directions?");
phraseNo = 0;
}
if(phraseNo == 0);
else
{
ObjectSortedList<String> phrases = new ObjectSortedList<String>(phraseNo);
for(int i = 0; i < phrases.length(); i++)
{
phrases.insert(phraseArray[i]);
}
print = new Lister<String>(phrases, phraseNo);
while(print.hasNext())
System.out.println(print.next());
}
}
}
After looking at your code I found multiple issues, here are they:
In your SortedListProgram class, in following code the phrases.length() will be 0, so the it will never go in that loop.
ObjectSortedList<String> phrases = new ObjectSortedList<String>(phraseNo);
for(int i = 0; i < phrases.length(); i++)
{
phrases.insert(phraseArray[i]);
}
Moreover in SortedListProgram class's this call sequence
print.hasNext() -> current.getData(index)
the index passed is equal to size of data array field in the
ObjectSortedList class and Since in java array indexes ranges from
zero to array size -1. So you are bound to get
java.lang.ArrayIndexOutOfBoundsException always.
Please correct your code.