All was well with this program until I made some changes in my addMainMenu method. Now it seems as though there is an array index out of bounds somewhere. Eclipse is not leading me too it. Does anyone know why this code has an array index out of bounds exception.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.LinkedList.checkElementIndex(Unknown Source)
at java.util.LinkedList.get(Unknown Source)
at Menu.main(Menu.java:58)
import java.util.LinkedList;
import java.util.List;
public class Menu {
LinkedList <LinkedList> mainMenuItems = new LinkedList <LinkedList> ();
public void Menu(){}
public boolean addMainMenuItem(String newItem, String existingItem, int position){
LinkedList <String> subMenuItems = new LinkedList <String> ();
for (int i = 0; i<= mainMenuItems.size(); i++){
if (mainMenuItems.get(i).contains(existingItem)){
subMenuItems.addLast(newItem);
int existingIndex = mainMenuItems.indexOf(existingItem);
if (position == 1){
mainMenuItems.add(existingIndex + 1, subMenuItems);
break;
}
if (position == -1){
mainMenuItems.add(existingIndex, subMenuItems);
break;
}
if (i == mainMenuItems.size()){
subMenuItems.addLast(newItem);
mainMenuItems.add(subMenuItems);
break;
}
}
}
}
return true;
}
public boolean deleteMainMenuItem(String item){
if (mainMenuItems.contains(mainMenuItems.indexOf(item))){
mainMenuItems.remove(mainMenuItems.indexOf(item));
return true;
}
else{
return false;
}
}
public static void main(String[] args){
Menu b = new Menu();
b.addMainMenuItem("h", "b", 1);
b.addMainMenuItem("hi", "h", 1);
b.addMainMenuItem("i", "h", 1);
System.out.println(b.mainMenuItems.get(0));
b.deleteMainMenuItem("hi");
System.out.println(b.mainMenuItems.get(0));
System.out.println(b.deleteMainMenuItem("hi"));
}
There are two possible issues
1. In this line
for (int i = 0; i<= mainMenuItems.size(); i++)
you should have use i < mainMenuItems.size()
2. when you have not assigned any value to your LinkedList, you try to access an index of your LinkedList
Change the <= to < in: i<= mainMenuItems.size()
EDIT:
If mainMenuItems is still empty, the line mainMenuItems.get(i).contains(existingItem) will generate java.lang.IndexOutOfBoundsException because mainMenuItems.get(i) doesn't exist.
First - Change the for loop as shown below
for (int i = 0; i < mainMenuItems.size(); i++)
Also, you need to restructure addMainMenuItem method as shown below -
for (int i = 0; i < mainMenuItems.size(); i++){
if (mainMenuItems.size() == 0) {
//you should put list initialization code here
//means, logic when there is nothing in the mainMenuItems list
} else {
//when the list is not empty
}
}
You are getting IndexOutOfBoundsException because you are doing get(index) on mainMenuItems - which is empty in your for loop.
For example -
List<String> list = new LinkedList<String>();
list.get(0); //will throw the same exception
Related
I was able to make the Constructor and capacity methods to works but don;t know why size(),isFull() and isEmpty() fails.I believe its pretty simple but i am just unable to see a minor error and fix it.Hope someone can clarify what i am doing wrong with thorough explaination.Also,my constructor works with the test file and it passes,but just want to know Is my constructor correct as specified by question?
import java.util.Arrays;
import java.util.Iterator;
public class SortedArray<T extends Comparable> implements
java.lang.Iterable<T> {
public SortedArray(int capacity) {
this.array = (T[]) new Comparable[0];
this.capacity = capacity;
this.size = 0;
}
public SortedArray(int capacity, T[] data) {
if(capacity > data.length)
{
this.capacity = capacity;
}
else {
this.capacity = data.length;
}
this.size = data.length;
this.array = (T[]) new Comparable[0];
}
final public int size() {
return this.size
}
final public int capacity() {
return this.capacity;
}
final boolean isEmpty() {
return size == 0;
}
final boolean isFull(){
return size == capacity;
}
#Override
final public Iterator<T> iterator() {
// Do not modify this method.
return Arrays.stream(array).iterator();
}
// Do not modify these data members.
final private T[] array; // Storage for the array's element
private int size; // Current size of the array
final private int capacity; // Maximum size of the array
}
//// Test File:
#Test
public void testConstructor() {
System.out.println("Constructors");
SortedArray array = new SortedArray(20);
assertEquals(array.size(), 0);
assertEquals(array.capacity(), 20);
Integer[] data = {1, 2, 3, 4};
array = new SortedArray(20, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 20);
array = new SortedArray(2, data);
assertEquals(array.size(), 4);
assertEquals(array.capacity(), 4);
}
#Test
public void testSize() {
System.out.println("size");
SortedArray arr = new SortedArray(10);
// Array is initially empty
assertEquals(arr.size(), 0);
// Inserting elements increases size
arr.add(12);
arr.add(13);
arr.add(14);
assertEquals(arr.size(), 3);
// Inserting duplicates increases size
arr.add(12);
arr.add(13);
assertEquals(arr.size(),5);
// Fill up the array
for(int i = 0; i < 5; ++i)
arr.add(i);
assertEquals(arr.size(), 10);
// Size does not change when array is full
arr.add(10);
arr.add(11);
assertEquals(arr.size(), 10);
// Removing elements decreases size
arr.remove(0);
arr.remove(1);
arr.remove(2);
assertEquals(arr.size(), 7);
// but removing elements that don't exist doesn't change anything
arr.remove(100);
assertEquals(arr.size(), 7);
// Removing from the empty array doesn't change size.
SortedArray empty = new SortedArray(10);
empty.remove(10);
assertEquals(empty.size(), 0);
}
#Test
public void testCapacity() {
System.out.println("capacity");
SortedArray array = new SortedArray(20);
assertEquals(array.capacity(), 20);
array = new SortedArray(100);
assertEquals(array.capacity(), 100);
Integer[] data = {1,2,3,4,5,6,7,8,9,0};
array = new SortedArray(20, data);
assertEquals(array.capacity(), 20);
array= new SortedArray(5, data);
assertEquals(array.capacity(), 10);
}
#Test
public void testIsEmpty() {
System.out.println("isEmpty");
SortedArray array = new SortedArray(10);
assertTrue(array.isEmpty());
array.add(10);
assertFalse(array.isEmpty());
array.remove(10);
assertTrue(array.isEmpty());
}
#Test
public void testIsFull() {
System.out.println("isFull");
SortedArray array = new SortedArray(5);
assertFalse(array.isFull());
array.add(10);
array.add(11);
array.add(12);
array.add(13);
array.add(14);
assertTrue(array.isFull());
array.remove(10);
assertFalse(array.isFull());
}
#Test
public void testIterator() {
}
testSize Failed : Expected <0> but was <3>
testCapacity Failed : Expected <5> but was <10>
testConstructor Failed : Expected <0> but was <4>
testisFull Failed : jUnit.framework.AssertionFailedError
testisEmpty Failed : jUnit.framework.AssertionFailedError
You forgot to include your "add(T toAdd)" and "remove(T toRemove)" methods, which when I was going through to make the tests pass, was the source of a vast majority of the fails. (Note: a trace of the fails would help, since your adds and removes need to be pretty complicated to fit the design it seems you intend)
Anyways, on to fixing what I can see.
In your second constructor, you never actually assign the data you take in. You call this.array = (T[]) new Comparable[0]; which creates an empty array of type Comparable. In reality, you need to call this.array = data in order to keep what's been given to you.
Another thing, in your size() method you forgot to place a semicolon after this.size. That tends to prevent things from passing.
Finally, final private T[] array can't have final, or you'll never be able to add or remove elements.
As a bonus, here are the add() and remove() methods I used to fit the requirements and make the tests pass (with comments!!!!):
public void add(T t) {
if (!(size >= capacity)) { //If there's room...
if (size == 0) //If the array is empty...
array[0] = t; //Add to first index
else
array[size] = t; //Add to next available index
size++;
}
}
public void remove(T element) {
if (size <= 0) //If the array is empty...
return; //Stop here
else {
for (int i = 0; i <= this.size(); i++) { //Linear search front-to-back
if (array[i].equals(element)) { //Find first match
array[i] = null; //Delete it
size--;
if (i != size) { //If the match was not at the end of the array...
for (int j = i; j <= (this.size() - 1); j++)
array[j] = array[j + 1]; //Move everything after the match to the left
}
return; //Stop here
}
}
}
}
On a side note, your calls to create SortedArray objects should really be parameterized (Using the <> such as SortedArray<Integer> arr = new SortedArray<Integer>(5, data);).
We are trying to compile our program, but we keep getting a NoSuchElementException. Anyone that has a clue on why this keeps occurring? Thanks in advance. In the following I will attach both the code where we implement the exception and also the main method.
EDIT - whole code in the following:
import java.util.Iterator;
import edu.princeton.cs.algs4.*;
public class RandomQueue<Item> implements Iterable<Item> {
private Item[] queue;
private int N;
private int size;
// Your code goes here.
public RandomQueue() { // create an empty random queue
N = 0;
size = 2;
queue = (Item[]) new Object[size];
}
public boolean isEmpty() {// is it empty?
if(N == 0) {
return true;
} else {
return false;
}
}
public int size() {// return the number of elements
return size;
}
public void resizeArray() {
if(3/4*size < N) {
size = size*2;
Item[] queueUpdated = (Item[]) new Object[size];
for(int i = 0; i < queue.length; ++i) {
queueUpdated[i] = queue[i];
}
queue = queueUpdated;
} else if (N < 1/4*size) {
size = size/2;
Item[] queueUpdated = (Item[]) new Object[size];
for(int i = 0; i < size-1; ++i) {
queueUpdated[i] = queue[i];
}
queue = queueUpdated;
}
}
public void enqueue(Item item) {// add an item
if(N < queue.length) {
queue[N++] = item;
resizeArray();
}
}
public Item sample(){ // return (but do not remove) a random item
if(isEmpty()) {
throw new RuntimeException("No such elements");
} else {
return queue[StdRandom.uniform(N)];
}
}
public Item dequeue(){ // remove and return a random item
if(isEmpty()) {
throw new RuntimeException("Queue is empty");
} else {
System.out.println(N);
int indexFraArray = StdRandom.uniform(N);
Item i = queue[indexFraArray];
queue[N] = null;
queue[indexFraArray] = queue[N--];
resizeArray();
return i;
}
}
private class RandomQueueIterator<E> implements Iterator<E> {
int i = 0;
public boolean hasNext() {
return i < N;
}
public E next() {
if (!hasNext()) {
throw new java.util.NoSuchElementException(); // line 88
}
i++;
return (E) dequeue();
}
public void remove() {
throw new java.lang.UnsupportedOperationException();
}
}
public Iterator<Item> iterator() { // return an iterator over the items in
random order
return new RandomQueueIterator();
}
// The main method below tests your implementation. Do not change it.
public static void main(String args[]) {
// Build a queue containing the Integers 1,2,...,6:
RandomQueue<Integer> Q = new RandomQueue<Integer>();
for (int i = 1; i < 7; ++i) Q.enqueue(i); // autoboxing! cool!
// Print 30 die rolls to standard output
StdOut.print("Some die rolls: ");
for (int i = 1; i < 30; ++i) StdOut.print(Q.sample() +" ");
StdOut.println();
// Let's be more serious: do they really behave like die rolls?
int[] rolls= new int [10000];
for (int i = 0; i < 10000; ++i)
rolls[i] = Q.sample(); // autounboxing! Also cool!
StdOut.printf("Mean (should be around 3.5): %5.4f\n", StdStats.mean(rolls));
StdOut.printf("Standard deviation (should be around 1.7): %5.4f\n",
StdStats.stddev(rolls));
// Now remove 3 random values
StdOut.printf("Removing %d %d %d\n", Q.dequeue(), Q.dequeue(), Q.dequeue());
// Add 7,8,9
for (int i = 7; i < 10; ++i) Q.enqueue(i);
// Empty the queue in random order
while (!Q.isEmpty()) StdOut.print(Q.dequeue() +" ");
StdOut.println();
// Let's look at the iterator. First, we make a queue of colours:
RandomQueue<String> C= new RandomQueue<String>();
C.enqueue("red"); C.enqueue("blue"); C.enqueue("green");
C.enqueue("yellow");
Iterator<String> I = C.iterator();
Iterator<String> J = C.iterator();
StdOut.print("Two colours from first shuffle: "+I.next()+" "+I.next()+" ");
StdOut.print("\nEntire second shuffle: ");
while (J.hasNext()) StdOut.print(J.next()+" ");
StdOut.println("\nRemaining two colours from first shuffle: "+I.next()+" "+I.next()); // line 142
}
}
I compile in cmd and this is the error I get
the error happens here:
enter image description here
and here:
enter image description here
Your iterator is modifying your collection. This is non-standard at least and seems to confuse yourself.
You are creating two iterators over your queue C, which has 4 elements in it at this time:
Iterator<String> I = C.iterator();
Iterator<String> J = C.iterator();
You ask the former iterator for two elements:
StdOut.print("Two colours from first shuffle: "+I.next()+" "+I.next()+" ");
This removes (dequeues) those two elements through this line:
return (E) dequeue();
Now your queue has 2 elements in it. N is 2.
Your try to remove the remaining 2 elements here:
StdOut.print("\nEntire second shuffle: ");
while (J.hasNext()) StdOut.print(J.next()+" ");
However, after one element has been removed, J.i is 1 and N is 1, so the iterator J considers the queue exhausted and only gives you this one element. There’s one left. N is 1. Yet you try to remove another two elements:
StdOut.println("\nRemaining two colours from first shuffle: "+I.next()+" "+I.next()); // line 142
This is bound to fail. Fortunately it does. next calls hasNext, which in turn compares:
return i < N;
I.i is 2 (since we had previously taken 2 elements from I) and N is 1, so hasNext returns false, which causes next to throw the exception.
The solution is simple and maybe not so simple: Your iterator should not remove any elements from your queue, only return the elements in order.
And the real answer: You should learn to use a debugger. It will be a good investment for you.
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
I need to create an array list using generics. My add method seems to work sometimes, however my get method appears to have a good amount of problems and i don't receive a compile error. However when i try to get an object from the Array list using my get method it throws a java out of bounds exception. here i what i have so far, and i am using BlueJ. Also, the instructions were to set the initial "illusion" length to zero.
public class AL <X> {
private X[]data;
private int count;
public AL() {
count = 0;
data = (X[]) new Object[0];
}
public void add (X v) {
if (data.length != count) {
data[count] = v;
count++;
} else {
X [] newdata = (X[]) new Object[data.length * 2];
for (int i = 0; i < data.length; i++) {
newdata[i] = data [i];
}
count++;
data = newdata;
}
}
public X get(int index) {
if (index >= count || index < 0) {
throw new ICantEven();
} else {
return data[index];
}
}
}
Your add method doesn't work, since the initial backing array you are using has a 0 length, which remains 0 even when you try to double it (since 0*2==0).
You also forgot to actually add the new element when you resize the backing array. If you hadn't forgot that, you'd get the exception in add.
First of all, change the initial size of the array created by your constructor to be positive :
data = (X[]) new Object[10];
Then add
data[count] = v;
to the else clause of your add method (just before count++;).
Your add method can be further simplified :
public AL()
{
count = 0;
data = (X[]) new Object[10];
}
public void add (X v)
{
// resize backing array if necessary
if (data.length == count)
{
X [] newdata = (X[]) new Object[data.length * 2];
for (int i = 0; i < data.length;i++ )
{
newdata[i] = data [i];
}
data = newdata;
}
// add new element
data[count] = v;
count++;
}
I wrote this program to find the item and then to remove all elements which are smaller than the item. The are no compilation errors, but when I run the program, the following message appears.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.remove(ArrayList.java:492)
at bb.deleteValues(bb.java:15)
at bb.main(bb.java:33)
Process completed. "
Code:
import java.util.ArrayList;
import java.util.Scanner;
public class bb {
public static boolean deleteValues(ArrayList<Integer> list, int item)
{ int p =list.indexOf(item);
if(!list.contains(item))
return false;
else
for(int i=p; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
list.remove(p);
list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
a.add(6);
a.add(4);
if(deleteValues(a,4))
for(int x : a)
System.out.print(x+ " ");
}
}
Your deleteValues method loops i from p to list.size()-1, but the loop's body contains list.get(i+1) and list.remove(i+1), so when i==list.size()-1, list.get(i+1) and list.remove(i+1) will attempt to access an item from an index not present in the list, which is the cause of the exception.
Removing the elements smaller than the passed item requires iterating over all the elements in the list, and comparing each one to the passed item. Note that when you remove the i'th element from the list, the (i+1)'th element becomes the new i'th element. That's why i should be incremented only if you don't remove an element from the list.
public static boolean deleteValues(ArrayList<Integer> list, int item)
{
int p = list.indexOf(item);
if(p<0)
return false;
for(int i=0; i<list.size();) {
if (list.get(i) < item) {
list.remove(i);
} else {
i++;
}
}
return true;
}
list.remove(i+1); will exceed the list size. For ex, when you are passing the 4th element, it will search for the element at 5th postion
The problem is in your deleteValues function, you loop while i is less than the size of the ArrayList, but add 1 when you call the get function, which can and will cause an IndexOutOfBoundsException, because it can make i equal to the size of the ArrayList, which is invalid. Change your for loop, and remove the cases where you have i+1, like so:
for(int i=p; i<list.size();i++ )
{
int n=list.get(i);
if (n>list.get(i))
list.remove(p);
list.remove(i);
}
Also, if your function is meant to remove all copies of a certain value, the code can be much, much simpler, and clearer:
public static boolean deleteValues(ArrayList<Integer> list, int item)
{
if (list.contains(item))
{
for (int i = 0; i < list.size(); i++)
if (list.get(i) == item)
list.remove(i);
return true;
}
return false;
}
import java.util.ArrayList;
import java.util.Scanner;
public class Ex {
public static boolean deleteValues(ArrayList<Integer> list)
{
for(int i=0; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
// list.remove(i);
list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
a.add(6);
// a.add(4);
if(deleteValues(a))
for(int x : a)
System.out.print(x+ " ");
}
}
you are adding one extra object to the arraylist with itz size specified and you are using index values wrongly in the deleteValues method so plz check with the both codes.
import java.util.ArrayList;
import java.util.Scanner;
public class Ex {
public static boolean deleteValues(ArrayList<Integer> list, int item)
{ int p =list.indexOf(item);
if(!list.contains(item))
return false;
else
for(int i=0; i<list.size();i++ )
{int n=list.get(i);
if (n>list.get(i+1))
list.remove(p);
//list.remove(i+1);
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>(8);
a.add(3);
a.add(10);
a.add(4);
a.add(5);
a.add(3);
a.add(2);
a.add(8);
//a.add(6);
a.add(4);
if(deleteValues(a,4))
for(int x : a)
System.out.print(x+ " ");
}
}
I am trying to wrtie java application that adds up to 5 long numbers using LinkedLists. At the end of the run I get this:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
0, Size: 0
at java.util.LinkedList.checkElementIndex(LinkedList.java:555) at java.util.LinkedList.remove(LinkedList.java:525) at
Assignment1.LongNumbers.remove(LongNumbers.java:33) at
Assignment1.LongNumbers.main(LongNumbers.java:92)
Here is the code:
import java.util.*;
/**
*
* #author .....
*/
public class LongNumbers
{
private List<Integer> [] theLists;
public LongNumbers() {
this.theLists = new LinkedList[6];
for (int i=0; i<6; i++)
this.theLists[i]= new LinkedList<>();
}
public void add(int location, int digit) {
//add digit at head of LinkedList given by location
theLists[location].add(digit);
}
public int remove(int location) {
//remove a digit from LinkedList given by location
return theLists[location].remove(location); //LongNumbers.java:33
}
public boolean isEmpty(int location) {
//check for an empty LinkedList given by location
return theLists[location].isEmpty();
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
//Local Variables
int digit;
int carry = 0;
int numberAt = 0;
int largestNumLength = 0;
char[] digits;
String number;
boolean userWantstoQuit = false;
LongNumbers Lists = new LongNumbers();
System.out.println("The program will enter up to 5 numbers and add them up.");
System.out.println();
while(!userWantstoQuit && numberAt != 5){
System.out.print("Enter a number, enter -1 to quit entry phase: ");
number = stdIn.nextLine();
if((number.compareTo("-1")) == 0)
userWantstoQuit = true;
else{
digits = new char[number.length()];
for(int i=0;i<number.length();i++)
digits[i] = number.charAt(i);
for(int i=0;i<number.length();i++){
int tempValue = digits[i] - 48;
try{
Lists.add(numberAt, tempValue);
}
catch(NumberFormatException nfe){
System.out.println("Invalid Input. Please try again.");
break;
}
if(i == (number.length() - 1))
numberAt++;
if(number.length() > largestNumLength)
largestNumLength = number.length();
}
}
}
for(int j=0;j<largestNumLength;j++){
int tempDigit = 0;
int index = 0;
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0); //LongNumbers.java:99
}
index++;
}
digit = carry + tempDigit;
if(j < numberAt){
carry = digit/10;
digit = digit%10;
}
Lists.add(5, digit);
}
System.out.print("The sum of the numbers is: ");
for(int i=0;i<Lists.theLists[5].size();i++){
System.out.print(Lists.theLists[5].get(i));
}
System.out.println();
System.out.println();
System.out.println();
}//end main
}//end class
For starters, I don't think you can have an array of List<E> objects...
You should also make sure your list is initialized and has an item at the given location.
So your method might look something like this:
public int remove(int location)
{
if(theLists != null)
if(theLists.size() > location)
return theLists.remove(location);
return 0;
}
If you need 2 dimensions of lists, you could try using List<List<E>>
Treat all E as Integer.
Look at the code here:
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0); //LongNumbers.java:99
}
index++;
}
You are checking whether the first element of the index'th list is not null. If that is true, you are adding it and call the remove method. However, what if you already processed the first list and index'th value is 1? In that case theLists[1].get(0) != null is true, but Lists.remove(0) passes 0 as location. Take a look at this code:
public int remove(int location) {
//remove a digit from LinkedList given by location
return theLists[location].remove(location); //LongNumbers.java:33
}
In the scenario I have described, location is 0. But your 0'th list is already empty...
EDIT: Rewrite the remove method, like this:
public int remove(int location, int index) {
//remove a digit from LinkedList given by location
return theLists[index].remove(location); //LongNumbers.java:33
}
And whenever you call this method, pass the index of the list to work with. Example:
while(index < numberAt){
if(Lists.theLists[index].get(0) != null){
tempDigit += Lists.theLists[index].get(0);
Lists.remove(0, index); //LongNumbers.java:99
}
index++;
}
Finally: In the future, please, structure your code, it was a real pain to read it in this, unstructured state, read about how to code.