insert element into Array index out of bounds java [duplicate] - java

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 have made an ADT called NumList, and have implemented it in a class NumArrayList
of the methods implemented, there is an insert(int i, double value) where value is inserted into array[i].
int numItems is a counter keeping track of my array's elements.
public void insert(int i, double value)
{
if (numItems >= items.length)
{
double[] tempItems = new double [items.length * 2];
for(int j =0 ; j < items.length; j++ )
{
tempItems[j] = items[j];
}
tempItems[items.length] = value;
items = tempItems;
}
else
{
if (i > numItems)
{
items[numItems] = value;
}
else
{
for (int k = i; k < numItems; k++)
{
items[k+1] = items[k];
}
items[i] = value;
}
}
numItems++;
}
is my method, looking simple enough.
public static void main (String[] args)
{
NumArrayList test;
test = new NumArrayList();
//System.out.println("this is how many initial items the initialized array has.");
//System.out.println(test.items);
test.insert(1, 0.1);
System.out.println("have tried to insert value 0.1 # position 1, that is the second element in array.");
test.print();
is my test code area, built into the same class.
I'm receiving an error where the compiler claims I have an ArrayIndexOutOfBoundsException at line 47, or at
tempItems[items.length] = value;
I believe it's trying to tell me that my initialization of items is wrong,
private double[] items;
private int numItems;
public NumArrayList()
{
items = new double[0];
numItems = 0;
}
but the initialization has already been approved by a much better programmer than I, and these errors are leading me nowhere. Perhaps a nudge as to which part of the program I should look into?

Your initialization is certainly wrong. What is a reasonable default size? For ArrayList the answer is 10. You can make it whatever you like, but not zero! If you double the length of an array with size 0, the new array still has length 0.
int capacity; //stores the size of the array (items available)
int numItems; //stores how many items are actually stored in the array.
public NumArrayList() {
items = new double[10];
numItems = 0;
capacity = 10;
}

You have to remember that array always starts with index 0 and not 1. So if your array size is 10, the maximum index is 9 and not 10.
tempItems[0] = first element;
tempItems[1] = second element;
etc etc
Assuming you have 10 elements, your tenth element will be in tempItems[9]. Trying to access tempItems[10] will throw the exception you're seeing. Basically if you're looking for the last index, you want to do:
tempItems[items.length-1] = value;
EDIT: Forget this. You're doubling your array index on initialization. Refer to Thorn's post above.

change this
tempItems[items.length] = value;
to
tempItems[items.length-1] = value;
array index starts with 0, if your array is of length 5, your last index would be 4

Once you allocate places to an array , lets say items = new double[0]; then you cannot change the size of the array. If the array is initialised to 0, that means you have a useless array. Anything you add to it, it will throw Array index out of bounds exception.
The way to go is by using Collections and specifically the List interface.
List myList = new List(); //Create an empty list
myList.add(item); //adds item to List
There are also other implementations of List, like ArrayList, LinkedList etc... that can fit better your needs .

Related

Int array sorting itself

import java.util.ArrayList;
public class Paaohjelma {
public static int pienin(int[] taulukko) {
int temp, size;
size = taulukko.length;
for(int i = 0; i<size; i++ ){
for(int j = i+1; j<size; j++){
if(taulukko[i]>taulukko[j]){
temp = taulukko[i];
taulukko[i] = taulukko[j];
taulukko[j] = temp;
}
}
}
return taulukko[0];
}
public static int pienimmanIndeksi(int[] taulukko) {
ArrayList<Integer> tauli = new ArrayList<>();
for (int i : taulukko) {
tauli.add(i);
}
return tauli.indexOf(Paaohjelma.pienin(taulukko));
}
public static int pienimmanIndeksiAlkaen(int[] taulukko, int aloitusIndeksi) {
// this methods should get the index of smallest value starting from specified index
int[] tempTauli = taulukko;
tempTauli = new int[tempTauli.length - aloitusIndeksi];
// this gets the right values to temporary array
if (aloitusIndeksi > 0) {
int index = 0;
int indexTauli = 0;
for(int value : taulukko) {
if(index >= aloitusIndeksi) {
tempTauli[indexTauli] = taulukko[index];
indexTauli++;
}
index++;
}
}
// values added are automatically sorted from smallest to largest?
// this shouldn't be, array should be 5, 99, 3, 12 but is shown as 3, 5, 12, 99
for(int inty : tempTauli) {
System.out.println(inty);
}
// get the index of smallest value in array
// index is 0 should be 2
int index = Paaohjelma.pienimmanIndeksi(tempTauli);
// return index of smallest value (add starting index to get the index of smallest value in the original array when starting from specified index)
return index+aloitusIndeksi;
}
public static void main(String[] args) {
// test code
int[] taulukko = {3, 1, 5, 99, 3, 12};
int minIndex = Paaohjelma.pienimmanIndeksi(taulukko);
System.out.println("Pienin: " + Paaohjelma.pienin(taulukko));
System.out.println("Pienimmän indeksi: " + minIndex);
System.out.println(Paaohjelma.pienimmanIndeksiAlkaen(taulukko, 2));
}
}
Hello! I'm doing some programming course work for school and have been stuck in this particular part for couple hours. So I decided it would be best for someone else to take a look and provide some light why my approach for this problem isn't working.
What should happen: class method PienimmanIndeksiAlkaen should return the index of smallest value in provided int array starting from specified index.
The main problem I have been having is that the array seems to be automatically sorting itself and I have no idea what is possible causing this. I have commented the relevant part of the code and would be more than happy if someone could explain why this is happening and what possible could be done to prevent this.
The reason your array is sorted is when you call
System.out.println("Pienin: " + Paaohjelma.pienin(taulukko));
you sort the array.
When you pass the array into this function, you aren't actually passing the value of the array, but the pointer to the array - the address of the array in memory. This is the difference between passing parameters by value or by reference.
How do you know if the value is passed by value or by reference?
As a rule of thumb:
primitive values - i.e. int, double, etc. will be passed by value - their value will be copied and passed to the function.
Any other type, namely arrays and classes, will be passed by reference - the address of the value in memory will be passed to the function, thus any change to the value inside the function will affect it when the function ends too.
Read more here

How to remove and add element from java array

I have a java array. I want to remove first d items from array and store it to some other array. I am able to store but not able to remove. My Code
private static void itemRemove(int[] inputArr, int d) {
int newArr [] = new int[d];
for(int i=0;i<d;i++){
newArr[i] = inputArr[i];
}
itemPrint(inputArr);
itemPrint(newArr);
}
So in example suppose I have array
inputArr is [1,2,3,4,5] and my d is 2
I am able to add in to newArray [1,2] but not able to remove from inputArr.
Also once I remove two element from inputArr which is having size 5 so I can add two more element. Can anybody give some idea how to add element.
You need to create a new int[]array of size inputArr.length - d and copy the values:
private static int[] itemRemove(int[] inputArr, int d) {
int[] newArrd = new int[d];
int[] newArr = new int[inputArr.length-d];
int newArrIdx = 0;
for(int i=0;i<inputArr.length;i++){
if(i<d){
newArrd[i] = inputArr[i];
}else{
newArr[newArrIdx++] = inputArr[i];
}
}
return newArr;
}
You can do it using System.arrayCopy and Arrays.fill functions
int[] inputArr = {1,2,3,4,5};
int n = 3; //number of positions to move
int[] newArray = new int[n];//creating new array of size n
System.arraycopy(inputArr, 0, newArray, 0, n);//copying elements up to nth position to new array
System.arraycopy(inputArr, n, inputArr, 0, inputArr.length-n);//copying remaining elements to start position
Arrays.fill(inputArr, inputArr.length-n, inputArr.length, 0);//filling cells after the last element with default 0 value
itemPrint(newArray);
itemPrint(inputArr);
To remove element from Array you need to remove the existing index of that element as well.
As array in java is immutable so you need to re-assign the array values to new array as you are doing already with newArr[index]
Just to remove array elements without altering index you may use the predefined library of commons.apache.org like this:
array = ArrayUtils.removeElement(array, element)
Apache Common
Or, you may use the arraylist instead of this for dynamic sizing of the array.You can initialize your input array like this:
ArrayList<> inputArr= new ArrayList<>();
To remove element from inputArr with index position just use the remove(int index) method of list.
inputArr.remove(your index here);
You're not doing any removal here:
for(int i=0;i<d;i++){
newArr[i] = inputArr[i];
}
You just copy the the value from the input array to the new array. The input array is unchanged.
Arrays in Java are of a fixed size so there is no way to remove elements. The typical way you can approximate this is to replace the element with some marker (or 'sentinel') value. For objects, this could be null. For primitive values, such as integers, you might just need to choose a value arbitrarily:
for(int i = 0; i < d; i++) {
newArr[i] = inputArr[i];
inputArr[i] = -999; //marked for removal
}
This is obviously not a very good solution. What if -999 is already in the array?
The correct way to deal with this is to use a List. Lists are not fixed-size, so it is possible to remove elements. There are multiple implementations you can use. ArrayList is the closest to an array.
Your function, changed to use an ArrayList, might look like this:
private static void itemRemove(List<Integer> inputArr, int d) {
List<Integer> newArr = new ArrayList<>();
int removed = 0;
while (removed < d)
{
newArr.add(inputArr.remove(0));
removed++;
}
itemPrint(inputArr);
itemPrint(newArr);
}
There's a few different things going on here. Most notably, we had an int[] and now we have a List<Integer>. We're using what's called "generics" and generics don't work with primitive types, so we need to use what's called the "boxed type".
The other noticeable change is that the loop is different. There are difficulties removing from collections while you are iterating over them and I structured the loop differently to avoid this problem.
You can do something like this:
public class Test {
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
System.out.println("Original Array");
itemPrint(array);
itemRemove(array, 2);
array = itemsLeft(array,2);
System.out.println("Original Array After Removing Items");
itemPrint(array);
}
private static void itemRemove(int[] inputArr, int d) {
int newArr [] = new int[d];
for(int i=0;i<d;i++) newArr[i] = inputArr[i];
System.out.println("New Array");
itemPrint(newArr);
}
private static void itemPrint(int[] array) {
for(Integer i : array) System.out.println(i);
}
private static int[] itemsLeft(int[] inputArr, int d) {
int [] itemsLeftArr = new int[inputArr.length-d];
for(int i=d, j=0; i<inputArr.length; i++, j++) {
itemsLeftArr[j] = inputArr[i];
}
return itemsLeftArr;
}
}
Output:
Original Array
1
2
3
4
5
6
New Array
1
2
Original Array After Removing Items
3
4
5
6
Elements cannot be removed from arrays. The only thing you can do is copy other elements to overwrite them. So, if your array looks like this:
1 2 3 4 5
You can copy 3, 4 and 5 down to overwrite 1 and 2, so you will be left with this:
3 4 5 4 5
(note how 4 and 5 are still there)
And then you can overwrite the last two elements with the new elements that you want to store in the array, which will leave you with this:
3 4 5 6 7
To copy elements, you can do it manually with a for loop, or you can use System.arrayCopy().

How to copy only certain elements of one Array to another in Java

I am struggling to create an array with the correct size according to my parameters I have set up. Long story short this program is dealing with a set number of elements in the first array. Those elements are as follows
int [] myWeights = {258, 58, 209, 91, 79, 182, 172, 27, 7, 29, 128, 198};
Now those elements are in ounces. I get the program to run everything correctly, now my professor wants us to separate the ones that are over 8 pounds into a new array. Those elements in the new array in this case are 258, 209, 182, 172, and 198. The problem is that the program, at the beginning, can create a randomly sized array with varying sized elements between the numbers 1-320. Is there a way to have some sort of loop instantiate the proper amount of "boxes" needed. Or am I just supposed to instantiate some arbitrary number and hope that is what I will need? My current code for this is
public static int [] overGivenPounds(int x, int [] array){
int pounds = 0;
int arrayLength = 0;
int arrayOverEightPounds[];
int k = 0;
for(int i = 0; i < array.length; i++){
pounds = array[i] / 16;
if(x < pounds){
arrayOverEightPounds[k] = array[i];
k++;
}
}
return arrayOverEightPounds;
If any of this seems unclear please ask, there is no need to be rude. I am very new to Java.
Use a loop to determine the size of the target array
Create the target array of the needed size
Use a second loop to put values in the target array
Without that first step, you cannot know the right size of the array. If you create an array that's even one element too small or one element two big, that will be a waste,
because you will be forced to create a 3rd array to return an array of the right size.
So your solution should look something like:
public static int[] overGivenPounds(int x, int[] array) {
int size = 0;
for (int value : array) {
if (satisfies(x, value)) {
size++;
}
}
int[] result = new int[size];
// ??? -> for you to complete this
for (int value : array) {
if (satisfies(x, value)) {
// ??? -> for you to complete this
}
}
return result;
}
public static int[] overGivenPounds(int x, int[] array){
Arrays.sort(array);
boolean foundSomething = false;
int startIndex = 0;
for (int i = 0; i < array.length; i++) {
if(array[i]/16>=x){
startIndex = i;
foundSomething = true;
break;
}
}
if(foundSomething)
return Arrays.copyOfRange(array, startIndex, array.length);
return null;
}
Are you allowed to use Java streams? If so, the solution would be:
return Arrays.stream(myWeights).filter(n -> n/16 > x).toArray();
If not then you could use Arrays.copyOfto create an array of the correct length:
int[] heavyWeights = int[myWeights.length];
int size = 0;
for (int weight: myWeights)
if (weight / 16 > x)
heavyWeights[size++] = weight;
return Arrays.copyOf(heavyWeights, size);
Are you allowed to use other classes? If so, you could just use an ArrayList and then use
//int arrayOverEightPounds[];
List<Integer> listOverEightPounds = new ArrayList<>();
//...
//arrayOverEightPounds[k] = array[i];
listOverEightPounds.add(array[i]);
//....
return listOverEightPounds.toArray(new Integer[0]);
to return an array of the proper size. In this case you can get rid of k. ArrayList uses an array internally but will resize it automatically if it needs more space so you don't have to do that micro-management. The toArray method on ArrayList will return a new array of the proper size if the array that's passed in is not big enough. A common thing you see is to just pass in an array of size 0 into toArray which means the returned value will always be the correctly sized array.
The usual way to do it is to create an array that you know can hold everything, add your items to that array, while keeping track of how many items you have added. At the end you return a copy of the array, truncated to the number of items.
Or, with Java 8, you can write it as a stream one-liner:
return Arrays.stream(array).filter(i -> (i / 16) > x).toArray();

How to check if an array is filled enough in java?

I want to check if an array is at 75% filled with objects and if it's true i have to resize it. In the variable size i have my objects (!=null) and i have an array of integers ints
public class PQ {
private int[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new int[capacity + 1];
this.size = 0;
}
public void insert(int number) {
//Code
}
private int[] resize() {
int[] newPQ = new int[this.pq.length * 2];
for (int i = 0; i < this.pq.length; i++) {
newPQ[i] = this.pq[i];
}
return newPQ;
}
}
Try this:
Whenever you add an element, we increment size (this will track the number of non-empty spaces so that you don't need to continually recount your array). Then we compare this number to the total length of your array. If count is at least 75% of the size of the array, we call your resize method and set pq to the new array it returns. I assume that you wish to add to the end of the array, and that you don't want empty indexs between numbers. If you want gaps you will need to use a loop which I am trying to avoid for efficiency's sake, if it isn't necessary. Assuming you don't, you can just add to your array at index size since this will be the first non-empty element.
//O(1) efficiency if you don't need to resize, O(n) if you do
public void insert(int number) {
if(size / pq.length >= 75) {
pq = resize();
}
pq[size] = number; //Since this will be the first non-empty index
size++;
return; //Doing it this way, if you can, is much more efficient than looping
}
If you call remove and take out from anything but the end you are going to have to shift everything down so that you don't have empty space.
If you are going to have empty indexes, try something like this (to insert at the first empty index encountered by the loop)...Let's use an Integer[] instead so that you can check for null and don't have to worry about any 0's in the array being counted as empty (int[] initiates everything to 0).
That way we can check for empty space and 0's are not counted as empty space in case you use any in your int[].
//O(n) efficiency if you don't need to resize, O(n^2) if you do
public void insert(int number) {
if(size / pq.length >= 75) {
pq = resize();
//You would have to make resize return an Integer[] and
//implement this throughout the code
}
for(int i = 0; i < pq.length; i++) {
if(pq[i] == null) {
pq[size] = number;
size++;
return;
}
}
}
Regardless:
Remember when you call remove() to decrement size.
What you could do is have an integer instance variable called count, that keeps track of the number of elements in the pq array. And whenever you insert an element into the array through the insert method, you can increment the count variable. Whenever you remove an element from the array through a remove method, you can decrement the count variable. Then, you can use this to check if the array is 75% filled at least,
if(pq.length * .75 <= size){
//do what you need to do here
}
And the class would look like this,
public class PQ {
private int[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new int[capacity + 1];
this.size = 0;
}
public void insert(int number) {
size++;
//Code
}
public void remove(int number) {
size--;
//Code
}
private int[] resize() {
int[] newPQ = new int[this.pq.length * 2];
for (int i = 0; i < this.pq.length; i++) {
newPQ[i] = this.pq[i];
}
return newPQ;
}
}
You are explicitly storing the size as a variable. You also know the backing array's size. Compare them at the point when you need to check size: if(this.size > 3*this.pq/4).
Use ArrayList do everything automatically for you in more efficient way.
Edited:
it is the initialization, all put -1
this.pq = new int[capacity + 1];
Arrays.fill(pq, -1);
then when you check you do like this:
if(pq[pq.length*.75] != -1) {
// then is means that is has already filled up 75%
} else {
// not filled 75% yet
}

Convert a range of lists to sub list and store them in an list of type linkedlist

I already have a list type Integer with values in it and I want to test sequentially from index zero if the sum of one range of elements satisfy a particular value then copy this range in an list and store it in a list of linkedlist. Then again test sequentially but now from the following index of the previous range, so if the previous range was index 0 to index 9 then start at index 10, and repeat the process until the last index.
List<Integer> arrayB = new LinkedList<Integer>(); //this is the array with values in it
List<LinkedList> p = new LinkedList<LinkedList>();// this is the array of arrays
List<Integer> arrayA = new LinkedList<Integer>();// this is the range or the sub list of arrayB
public void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
int count = 0;
for (int w : arrayB)
{
count = w + count;
arrayA.add(w);
if(count == n)
{
count = 0;
p.add((LinkedList) arrayA);
arrayA.clear();
}
}
}
However, this code fail when I call method clear in arrayA so is there any alternative to code with this logic regardless of the data structure used?
My understanding of the problem is the following:
There exists an array from which you would like to extract a certain range of values given that they satisfy some criteria. In this case, the criterion is that the range evaluates to some sum. Once this has been completed, you would like to repeat the process until all of the values in the original data-structure have been exhausted.
I will assume that your original data-structure is an array of integers, and that your resulting data-structure is a linkedlist of integer arrays.
One way to do it may be to keep a global counter that keeps track of the current index of the original array, such as something like the following:
int[] originalArray = {//list of numbers separated by commas};
LinkedList<Integer[]> resultingList = new LinkedList<>();
int currentIndex = 0;
public static void function(int totalSum) {
int currentSum = 0;
int initialIndex = currentIndex;
while((currentSum != totalSum) && (currentIndex < (originalArray.length - 1))) {
if(currentSum + initialArray[currentIndex] <= totalSum) {
currentSum += initialArray[currentIndex];
currentIndex++;
}
else {
break;
}
}
if(currentSum = totalSum) {
int[] arrayToAdd = new int[currentIndex - initialIndex - 1];
for(int i = 0; i < currentIndex - initialIndex; i++) {
arrayToAdd[i] = originalArray[initialIndex + i];
}
resultingList.add(arrayToAdd);
}
}
You are using the same list reference arrayA every time you add a sub list into p, every list element in p is pointing to the same arrayA . So when you call arrayA.clear(); You clear all the list elements in p.
To correct that, you need to create a new list object when you add a sublist to arrayA:
public static void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
int count = 0;
LinkedList<Integer> subList = new LinkedList<>();
for (int w : arrayB) {
count = w + count;
subList.add(w);
if (count == n) {
count = 0;
p.add((LinkedList) subList); // p is adding a new list reference every time
subList = new LinkedList<>(); // create a new list object, subList points to a new list object
}
}
}
The issue is that when you add your linked list into the final storage p, you are assuming the elements of the list are put in there. Only a pointer is referenced, so when you clear it the next line, all the elements are gone.
p.add((LinkedList) arrayA);
arrayA.clear();
One tip is to move arrayA's scope to inside the function. This is because it's temporary, and only a sublist, so it shouldn't be at the instance level. It can be reused by doing a
arrayA = new LinkedList<Integer>();
and when doing so, you haven't lost the old list because p is keeping a reference to it.
Another tip is to name your lists with meaningful names.
originalIntList, groupedIntList, singleGroupIntList help the reader figure out what they could be doing more than a comment stating obvious aspects of the Java object.

Categories