Java ArrayList is throwing IndexOutOfBoundsException. Why? - java

This is my current progress on a project. I am trying to implement this ArrayList stuff but file continues to trow the same exception.
import java.util.*;
public class Numerican{
public static void main( String [] args ){
Scanner input = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<Integer>(10);
int count = input.nextInt() * 2;
while (count > 0){
array.add( 0 );
count = count - 1;
array.add(count, 2);
}
array.add(2, input.nextInt());
System.out.println(array.get(2));
}
}
It was my understanding that = new ArrayList<Integer>(10); would set the array size to 10. Did I do something wrong?

= new ArrayList<Integer>(10);
This line initializes the CAPACITY to 10, meaning the memory is allocated in the backend, but as far as you are concerned, the array is still empty.
Javadoc -
public ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.
This is why the calls to add might fail, if you try to add beyond the size of the ArrayList.
p.s. remember that add function takes index first and then element, when using the 2 parameter variant.
Edit:
ArrayList has 2 different member variables, size and capacity. Capacity is how much memory is allocated, size is how many elements are inserted by programmer.
Here, Capacity = 10, Size = 0;

According to the javadocs:
Constructs an empty list with the specified initial capacity.
Note that the ArrayList is empty (i.e. does not contain any items). The value indicates the capacity of the ArrayList which is the number of elements which can be added before more memory must be allocated.
On the other hand, calling add() actually adds an item to the ArrayList. In your example, array.add( 0 ); adds a 0 at the end of the list and array.add(count, 2); adds a 2 at index count. I suspect the problem is that count is not a valid index in your ArrayList. You should check what its value is by inserting an SOP or using a debugger.

count maybe >= 10, maybe souce code can answer you question:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
rangeCheckForAdd():
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

if the index is out of range (index < 0 || index > size()) IndexOutOfBoundsException will be thrown.
So i think you are accessing index > size() of the list.
size() ===> Returns the number of elements in this list.
array.add(2, input.nextInt()); here is the possible exception when your list size is 1...

From my understanding of ArrayList, you need to add items to the list in a sequential index.
i.e. You cannot add an item to the 7th index position if 1 to 6 have not been filled in.
ArrayList.add(indexPosition, element);
If you add elements to the list, starting at indexPosition 0, and increasing the indexPosition by 1 each time, it should work.
Ex.
int i = 0;
(while i < 10){
array.add(i, numberToAdd);
i++; }

Hey seems like your Problem is because of the line
array.add(count, 2);
adds a 2 at index count
For example your input size is 5 then array.add(9,2); the array size is only 1 by that time as capacity and size are two different parameters for a ArrayList. So you can use a for loop instead of while to insert your values
for(int i=0; i<count;i++)
{
array.add(i,2);
}

Related

How to make a loop to insert item in between all elements of an array

I have an an array [1,1,1,1,1,1] and I want to make a for loop that will insert a 0 in between all the 1s.
I’ve tried using
for(int i=0;i<array.length;i+2) {
insertItem(array,i,0);
}
But this doesn’t work since the array increases in length every time you insert an item, and my client crashes.
Create a new array that is twice the length of the input, then loop through your input array and for each element, add it to the new array followed by a 0 updating an index as you go so that you are putting your 1s and 0s in the right position.
Not sure if you want a 0 at the end, if not adjust the details above accordingly (eg new array is twice size of input minus 1)
I'm assuming insertItem increases the length of array as needed. In that case the trick is to calculate the number of new insertions required (array.length - 1) before starting the loop. New values are inserted at odd locations, given by 2*i+1
int n = array.length - 1;
for(int i=0; i<n; i++) {
insertItem(array, 2*i+1, 0);
}
An alternative would be to create a new array and populate it like this:
int[] narr = new int[2*arr.length-1];
for(int i=0; i<narr.length; i++) {
narr[i] = (i % 2 == 0) ? arr[i/2] : val;
}
I think you just created an infinite loop. In your for loop, the i+2 should be replaced by i+=2. If not, the condition will never be met.

Java Code More Efficient

I am creating a code here but I believe there is a way making the following more efficient. I tried many ways but it does not seem to work.
protected void randomise() {
int[] copy = new int[array().length]; //This makes the new int called randomIndex
// used to indicate if elements have been used
boolean[] used = new boolean[array().length]; //calling "used" as a new boolean for the array
Arrays.fill(used,false);
/**
* if index = 0, it means their is nothing in the index.
* if you apply a random number, it will copy that number to an array called index.
* if randomIndex in use, then the boolean becomes true.
*/
for (int index = 0; index < array().length;) {
do {
randomIndex = randomIndex();
} while (used[randomIndex]); //when random is in use, do the follow instruction.
copy[index] = array[index]; //copy the value value to an array called index.
used[randomIndex] = true; //when randomIndex is in use, then it becomes true.
}
//Of course, if there an extra random stores in the array, the index list is increased by one (index++).
for (int index =0;index < array().length; index++) {
array()[index] = copy[index]; //This tells where to copy the index value. in this case, it is a index array.
}
Do you have to use randomIndex?
If not you can use your bool[] to eliminate that do {} while() by sequentially adding the value to copy (which isn't a great name) and choosing a randInt in the range of the len of elements that haven't been selected, then using that bool[] to count a walk through the array elements ( to make your choice for the next element in copy.
You seem to want to randomly re-order an array. If so, then indeed there is a much more efficient solution. You are currently keeping two extra arrays on the size of the input (O(n)) while you do not have to.
The random shuffling is a common problem, and obviously there have been proposed several algorithms to accomplish this task. One of the most efficient algorithms is Knuth's algorithm for random permutation
The algorithms idea is, loop over the array once, and for each number i, perform a random exchange between i and a (random) array index between 0 and i. This guarantees that the array with be shuffled (meaning that each item will have equal possibility to be placed in each of the array indexes), in O(n) time and without using any extra space.
In short,
for (int i = 0; i < index; i++) {
int r = random.nextInt(i + 1);
exchange(array, i, r);
}
It is simple - use some collection of indexes and remove element when you used it. This way should looks like:
List<Integer> indexes = new ArrayList<>(array.length);
for (int i = 0 ; i < array.length ; i++) {
indexes.add(i);
}
Random r = new Random();
while (indexes.size() > 0) {
int randomIndex = r.nextInt(indexes.size());
int index = indexes.remove(randomIndex);
copy[index] = array[index];
}
Please note that:
you should check what is exact collection will be more efficient in your situation
Another way - create list values for array and use Collections.shuffle method on this list.
Additional another way - use some recursive algorithm to do that work.

Handle ArrayIndexOutBoundException

I am facing Array Index OutboundException when runs the code..
My code here
public void putValuesForDeleteAction(HashMap map ,Object[] colNames,Object[] colValues,Object[] colDataTypes){
try{
if(colNames!=null && colNames.length > 0 && colValues!=null && colValues.length >0 &&
colDataTypes!=null && colDataTypes.length >0){
int i = 0;
i = colNames.length ;
colNames[i]="LAST_UPDATE_BY";
colValues[i]=(String)map.get("LAST_UPDATE_BY");
colDataTypes[i]="VARCHAR2";
i++;
colNames[i]="LAST_UPDATE_DATE";
colValues[i]=(String)map.get("LAST_UPDATE_DATE");
colDataTypes[i]="TIMESTAMP";
System.out.println("mapValues is "+map);
}else{
// do nothing
}
}catch(Exception e){
e.printStackTrace();
}
}
Error logs
2014-09-17 10:47:51.026 ERROR [STDERR] java.lang.ArrayIndexOutOfBoundsException: 9
ArrayIndexOutOfBoundException means it does not found any element at index position which you specifying
in your case you first assign object array length to i by i = colNames.length ;
suppose your array length is 4
means your array last index is 3 because index start from 0,1,2,3 total length 4
so replace
i = colNames.length ;
with
i = colNames.length - 1 ;
and again you are doing i++ which is again wrong statement
conclusion is ArrayIndexOutOfBoundException occurs when your i > array length
You can use System.arrayCopy to copy existing array to an array of more size and aviod the exception.
Below copyFrom is the original array and copyTo is the destination array of larger size.
System.arrayCopy(copyFrom, 0, copyTo, 0, copyFrom.length);
This piece of below code is causing problem.
colNames[i] = "LAST_UPDATE_BY";
colValues[i] = map.get("LAST_UPDATE_BY");
colDataTypes[i] = "VARCHAR2";
colNames[i] = "LAST_UPDATE_DATE";
colValues[i] = map.get("LAST_UPDATE_DATE");
colDataTypes[i] = "TIMESTAMP";
Once value of i is more than the array length, it will give this exception.
java.lang.ArrayIndexOutOfBoundsException
Eg: suppose length of any array is 2, so at max you can access [0] and [1], but if you try to access [2], it will throw the above exception.
Solution to your problem
Since you are trying to add new elements in all the three arrays, you must increase or set the size before hand.
Including on #Aryan request, just run below program and analyze
public static void main(String[] args) {
// declaring array of size 2, ie it will contain max 2 elements
String[] myArray = new String[2];
System.out.println("accessing 1 element");
System.out.println(myArray[0]);
System.out.println("accessing 2 element");
System.out.println(myArray[1]);
// while accessing 3rd element, it will give error, since size is defines as 2.
System.out.println("accessing 3 element");
System.out.println(myArray[2]);
}
I would suggest you use an ArrayList as you won't have to worry
about the length anymore. Once created, you can't modify an array
size:
An array is a container object that holds a fixed number of values
of a single type. The length of an array is established when the array
is created. After creation, its length is fixed.

Checking to see if array is full

If I have an Array Candy[] type;
and type = new Candy[capacity];
if the Array is full is capacity = type.length ?
Since you are using array, the size of array is determined during compilation. Thus if your intention is to check whether current array's index has reached the last array element, you may use the following condtion (possibly in a loop) to check whether your current array index is the last element. If it is true, then it has reached the last element of your array.
Example:
int[] candy = new int[10]; //Array size is 10
//first array: Index 0, last array index: 9.
for (int x=0; x < candy.length; x++)
if (x == candy.length - 1)
//Reached last element of array
You can check the size of the array by using:
candy.length
You check whether it is last element by using:
if (currentIndex == candy.length - 1) //Where candy is your array
Make sure you are using double equal == for comparison.
Single equal = is for assignment.
Java creates an array with capacity count of references to the Candy instances initializing array with the nulls. So any array in java is full and
type.length == capacity
is always true.
type = new Candy[capacity] is equivalent to
type = new Candy[] {null, null, null, /* capacity count of nulls */, null};
In the example you show type.length will always be equal to capacity(after the initialization). Also your array will always have capacity elements but they will initially all be null.
If you want to check if array is full (no null elements), use something like this:
//1
boolean b = false;
//2
for(int i = 0; i < type.length; i++){
if(type[i] == null){
b = true;
}
}
//3
if(b == false){
System.out.println("Array is full");
}
What does it mean?
//1. At beginning you have one boolean (b) which is false.
//2. If any value in your array is null, b will be true.
//3. You check if value of b is still false. If it is, that means that b is never changed, so array is full (no null elements) .

Two-Dimensional ArrayList set an element

I have this piece of code:
List<ArrayList<Integer>> tree = new ArrayList<ArrayList<Integer>>();
tree.add(0, new ArrayList<Integer>(Arrays.asList(1)));
tree.add(1, new ArrayList<Integer>(Arrays.asList(2,3)));
tree.add(2, new ArrayList<Integer>(Arrays.asList(4,5,6)));
I would like, for example, to replace 5 with 9. how can I do this?
use
tree.get(2).set(1,Integer.valueOf(9));
to get the ArrayList at the position 2 and then set the second element to 9.
tree.get(2).set(1, 9)
This gets the third (i.e. index = 2) element of the outer ArrayList, which returns the inner ArrayList. Then set the 2nd element (index = 1) to 9. Autoboxing takes care of the int to Integer conversion.
find index of elements that you want to replace and use twice set(index, newElement)
method to do the replacement
The major methods we use in a 2-Dimensional ArrayList are -->
let say we have a 2-Dimensional ArrayList as
ArrayList<ArrayList<Integer>> ArrayList_2D = new ArrayList<>()
To find the size
ArrayList_2D.size();
To access some element at position (i , j)
ArrayList_2D.get(i).get(j);
To set value of an element at position (i , j) equal to x
ArrayList_2D.get(i).set(j , x);
To remove (i , j) element
ArrayList_2D.get(i).remove(j);
To find the index of first occurring of element y
int col , row;
for(int a=0;a<ArrayList_2D.size();a++){
for(int b=0;b<ArrayList_2D.size();b++){
if(ArrayList_2D.get(i).get(j)==y){
col = i;
row = j;
break;
}
}
}
Hope This Is Will Be HelpFul

Categories