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.
Related
it's my first time ever posting on StackOverFlow, because I'm truly desperate right now. I couldn't find an answer for my problem anywhere, so long story short, I have some kind of project for my Data Structures course. The project had 2 parts. The first part was implementing a Sorted Array Bag/ Sorted Collection for some problem. We are using java.
The second part is where I do actually have a lot of problems. So the main idea is implementing a doubly-linked list from the sorted-array bag/ sorted collection and in a way that I would just switch sorted array bag with doubly-linked list in my main and everything should work the way it was working before.
The main thing about the SortedArrayBag is as far as I understand using a Comparator when you declare the SortedArrayBag in your main, and it looks like this:
SortedBag<Grupe> al = new SortedArrayBag<>(new ComparatorVot());
al.add(new Grupe("gr1", 5));
al.add(new Grupe("gr2", 7));
The sorted collection/sorted array bag was implemented by my teacher because there is no such data structure in Java, here is her implementation:
public class SortedArrayBag<T> implements SortedBag<T> {
private ArrayList<T> elemente;
private Comparator<T> relatie;
public SortedArrayBag(Comparator<T> rel) {
this.elemente = new ArrayList<>();
this.relatie = rel;
}
public void add(T elem) {
int index = 0;
boolean added = false;
while (index < this.elemente.size() && added == false) {
T currentElem = this.elemente.get(index);
if (relatie.compare(currentElem, elem) < 0) {
index++;
} else {
this.elemente.add(index, elem);
added = true;
}
}
if (!added) {
this.elemente.add(elem);
}
}
public void remove(T elem) {
boolean removed = this.elemente.remove(elem);
}
public int size() {
return this.elemente.size();
}
public boolean search(T elem) {
return this.elemente.contains(elem);
}
public Iterator<T> iterator() {
return this.elemente.iterator();
}
}
And the SortedBag interface looks like this
public interface SortedBag<T> {
public void add(T elem);
public void remove(T elem);
public int size();
public boolean search(T elem);
public Iterator<T> iterator();
}
Also in case it helps, the comparator looks like this:
public class ComparatorVot implements Comparator<Grupe> {
public int compare(Grupe o1, Grupe o2) {
Grupe gr1 = (Grupe) o1;
Grupe gr2 = (Grupe) o2;
if (gr1.getNrPersoane() / 2 + 1 == gr2.getNrPersoane() / 2 + 1) {
return 0;
} else if (gr1.getNrPersoane() / 2 + 1 > gr2.getNrPersoane() / 2 + 1) {
return 1;
} else {
return -1;
}
}
}
So, I tried my best implementing doublyLinkedList using a SortedArrayBag, this is what I did, also if it helps making my code more clear, prim=first, ultim=last, urmator=next, anterior=previous
import java.util.Iterator;
public class LDI {
private Nod prim;
private Nod ultim;
//private int lungime;
public LDI() {
this.prim = null;
this.ultim = null;
//this.lungime = 0;
}
public class Nod {
private int elem;
private int frecventa;
private Nod urmator;
private Nod anterior;
public Nod(int e, int f) {
this.elem = e;
this.frecventa = f;
this.urmator = null;
this.anterior = null;
}
}
public void add(int elem, int frecventa) {
Nod nodNou = new Nod(elem, frecventa);
nodNou.elem = elem;
nodNou.frecventa = frecventa;
if (prim == null) {
this.prim = nodNou;
this.ultim = nodNou;
} else if (frecventa <= prim.frecventa) {
nodNou.urmator = prim;
this.prim.anterior = nodNou;
this.prim = nodNou;
} else if (frecventa >= prim.frecventa) {
nodNou.anterior = prim;
for (; nodNou.anterior.urmator != null; nodNou.anterior = nodNou.anterior.urmator) {
if (nodNou.anterior.urmator.frecventa > frecventa)
break;
}
nodNou.urmator = nodNou.anterior.urmator;
if (nodNou.anterior.urmator != null) {
nodNou.anterior.urmator.anterior = nodNou;
}
nodNou.anterior.urmator = nodNou;
nodNou.anterior = nodNou.anterior;
}
}
public void remove() {
if (this.prim != null) {
if (this.prim == this.ultim) {
this.prim = null;
this.ultim = null;
} else
this.prim = this.prim.urmator;
this.prim.anterior = null;
}
}
public int size() {
int count = 0;
for (Nod nodNou = prim; nodNou != null; nodNou = nodNou.urmator)
count++;
return count;
}
public class MyIterator {
private Nod curent;
public MyIterator() {
this.curent = prim;
}
public void urmator() {
this.curent = this.curent.urmator;
}
public int getElem() {
return this.curent.elem;
}
public boolean valid() {
if (this.curent != null) {
return true;
} else {
return false;
}
}
}
public Iterator iterator() {
return new MyIterator();
}
}
The thing is, it doesn't work, I have no idea how to make my data structure able to receive the Comparator I used and also the Iterator doesn't work. If you have any idea how to make this work, please do help me.
I am trying to create a program where when the stack is full(for example 5 values can be held), and you try to push another value on the stack it performs the DropOut method. Where is sets ex. stack at position 0 to position 1 etc.... all the way to position 3 == to position 4. From here I want to delete the top value on the stack ( in this example it is the value at position 4 (5th value) ) From here I would then be able to add my next value to the top of the stack.... but my code is not working as intended. I am a beginner and appreciate any input available. Thanks for you time.
package jsjf;
import jsjf.exceptions.*;
import java.util.Arrays;
import java.util.*;
public class ArrayStack1<T> implements StackADT<T>
{
private final static int DEFAULT_CAPACITY = 5;
private int top;
private T[] stack;
private int next;
public ArrayStack1()
{
this(DEFAULT_CAPACITY);
}
public ArrayStack1(int initialCapacity)
{
top = -1;
stack = (T[])(new Object[initialCapacity]);
}
public void push(T element)
{
if (top+1==DEFAULT_CAPACITY){
DropOut();
//top=top-1;
pop();
stack[top]=element;
}
top++;
stack[top] = element;
}
public void DropOut(){
for (int x=0; x<stack.length-1; x++){
// if(x==stack.length){
// stack[x]=null;
// }
stack[x]=stack[x+1];
}
}
public T pop() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
T result = stack[top];
stack[top] = null;
return result;
}
public T peek() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
return stack[top];
}
public boolean isEmpty()
{
return (top < 0);
}
public int size(){
return (top+1);
}
public String toString()
{
String result = "";
for (int scan=0; scan <= top; scan++)
result = result + stack[scan].toString() + "\n";
return result;
}
public static void main(String[] args) {
ArrayStack1<Integer> t1=new ArrayStack1<Integer>(5);
t1.push(5);
t1.push(3);
t1.push(6);
t1.push(5);
t1.push(3);//
t1.push(4);
}
}
On push you are stacking the element twice when you reach max capacity. An else should fix your issue:
public void push(T element)
{
if (top+1==DEFAULT_CAPACITY){
DropOut();
//top=top-1;
pop();
stack[top]=element;
} else {
top++;
stack[top] = element;
}
}
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.
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.
I get stack overflow error when I try to load(). I am trying to read PhoneBookEntry objects from a txt file. The txt file has a name and number which make up the PhoneBookEntry object.
Can you please let me know what I'm doing wrong?
package HashSet;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Scanner;
public class PhoneBook {
int capacity = 10;
private ArrayList<PhoneBookEntry>[] buckets;
public PhoneBook() {
this(10);
}
public PhoneBook(int size) {
capacity = size;
buckets = new ArrayList[size];
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new ArrayList<PhoneBookEntry>();
}
}
public int getSize() {
int tot = 0;
for (ArrayList<PhoneBookEntry> x : buckets)
tot += x.size();
return tot;
}
public boolean add(PhoneBookEntry entry) {
if (contains(entry))
return false;
int x = Math.abs(entry.hashCode());
buckets[x % buckets.length].add(entry);
return true;
}
public void load()
{
InputStream is = getClass().getClassLoader().getResourceAsStream("phone.txt");
Scanner scan = new Scanner(is);
if (scan.hasNext())
add(new PhoneBookEntry(scan.next());
}
public void bucketSize() {
for (int i = 0; i < buckets.length; i++)
System.out.println(i + " " + buckets[i].size());
}
public boolean contains(PhoneBookEntry word) {
int x = Math.abs(word.hashCode());
return buckets[x % buckets.length].contains(word);
}
public int getCapacity() {
return capacity;
}
public static void main(String[] args) {
PhoneBook phone = new PhoneBook();
phone.load();
}
}
package HashSet;
import java.util.LinkedList;
import java.util.ListIterator;
public class PhoneBookEntry {
String n;
Integer nr;
LinkedList<PhoneBookEntry> list;
public PhoneBookEntry(String name, int number) {
list = new LinkedList<PhoneBookEntry>();
n = name;
nr = number;
list.add(new PhoneBookEntry(n, nr));
}
public String getN() {
return n;
}
public void setN(String n) {
this.n = n;
}
public Integer getNr() {
return nr;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((n == null) ? 0 : n.hashCode());
result = prime * result + ((nr == null) ? 0 : nr.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PhoneBookEntry other = (PhoneBookEntry) obj;
if (n == null) {
if (other.n != null)
return false;
} else if (!n.equals(other.n))
return false;
if (nr == null) {
if (other.nr != null)
return false;
} else if (!nr.equals(other.nr))
return false;
return true;
}
public void setNr(Integer nr) {
this.nr = nr;
}
#Override
public String toString() {
return n + " " + nr;
}
}
Every new phone book entry creates a new phone book entry that creates a new phone book entry that creates a new phome book entry, etc... ad infinitum. That is, until the stack space runs out.
You need to rethink your application data structure.
public PhoneBookEntry(String name, int number) {
list = new LinkedList<PhoneBookEntry>();
n = name;
nr = number;
list.add(new PhoneBookEntry(n, nr));
}
is causing an infinite recursion. You likely need a new class to put in the linked list (PhoneNumber or some such if a PhoneBookEntry can contain multiple names/numbers, otherwise ditch it.)