adding names/values in list - java

I keep getting an IndexOutOfBoundsException when I run the executable. The first name and min_cost print before the error. I know that it is probably trying to access an index that can't be accessed. I can not figure out what is wrong.
for(int j = 0; j <= no_comps-1; j++){
String line2 = in.nextLine();
Scanner compline = new Scanner(line2);
int k = j-1;
String co_name = compline.next();
int x = compline.nextInt();
int y = compline.nextInt();
int val = compute(tot_boxes,my_boxes,x,y);
List <String> names = new ArrayList <String>(500);
names.add(j,co_name);
List <Integer> min_cost = new ArrayList <Integer>(500);
min_cost.add(j,val);
while(j > 1){
if(min_cost.get(j) > min_cost.get(k)){
Collections.swap(names, j, k);
Collections.swap(min_cost, j, k);
}
else{
}
}
System.out.println(names.get(j)+ " " +min_cost.get(j));
Thanks in advance for any help!
Edit:
DHL 46
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:612)
at java.util.ArrayList.add(ArrayList.java:426)

Edit: Now that you have posted the stack trace, please check if (min_cost.size()==0) as you are trying to access the second element 1 when the list size is 0.
I would suggest you to declare Lists outside for loop:
List <String> names = new ArrayList <String>(500);
List <Integer> min_cost = new ArrayList <Integer>(500);
for (...) {
// Your code
}
and use the list variables inside to access values.
What is happening right now is that you are creating new Lists every time the loop is executed. The problem starts when the value of j=2. You again create new Lists and assign values.
But then for j=2 your if (j>1) becomes true and you try to compare
if(min_cost.get(j) > min_cost.get(k))
You have initialized k as:
int k = j-1;
so for j=2:
k=1
And min_cost.get(k) -> min_cost.get(1)
But since you created new Lists inside for loop that value doesn't exist.
Hence, it throws IndexOutOfBoundsException.

Why are you recreating the names and min_cost objects within the loop? Whatever you add to the ArrayList will be gone each iteration of the loop. I'm guessing the Exception occurs when you try to call min_cost.get(k). Try putting these lines above the for-loop:
List <String> names = new ArrayList <String>(500);
List <Integer> min_cost = new ArrayList <Integer>(500);

Related

Compare elements from an ArrayList

I have a small problem, I want to go through a list and compare two objects of the array. Each object has 3 elements, I use a StringTokenizer to be able to remove the separator, so each object has 3 elements. I would like to know how to make a method that gets the third element of each object and compare them. And if that element is less than another delete that element and the 2 before it.
I tried to make them with an iterator but I wouldn't know very well that it started from the 3 element and increased the position by 3.
Iterator<Integer> it = lisM.iterator();
int num;
while (it.hasNext()){
num = it.next();
System.out.println(num);
}
Is --> if, I was wrong to put it in the picture
This only answers part of your question. I could not understand the question completely, please edit it and I can edit my answer.
You should not remove items from a list whilst in a for loop, therefore you can, for example, create another boolean list with the same size divided by 3 and just fill it with true Booleans then set the position divided by 3 to false if you want to delete the three items. Then you can create a new list, iterate over the boolean list and add 3 "Objects" which are actually Strings (thanks #JB Nizet) at a time, every time the boolean list element is true. When it is false you just don't add the elements and by doing so you are practically deleting the two elements before that element together with that element.
You casted a String to an int, that does not work you have to parse the Strings.
I corrected some of your code and added the boolean list here:
ArrayList<String> lisM = new ArrayList<>(); // here I initialise the list as an array list with strings.
ArrayList<Boolean> booleanList = new ArrayList<>();
for (int i = 0; i < lisM.size() / 3; i++) {
booleanList.add(true);
}
for(int i = 3; i < lisM.size();i+=3) {
int m = Integer.parseInt(lisM.get(i)); // here I changed the casting to parsing and moved it out of the for loop, there is no need to initialize it again every single time since you do not change it in the second for loop.
for (int j = 6; j < lisM.size(); j += 6) {
int m1 = Integer.parseInt(lisM.get(j));// here I changed the casting to parsing again.
if (m > m1) { // this makes no sense here because you are going over all of the elements of the list and comparing them to all of them. But I kept it here for the sake of example.
booleanList.set(i/3,false);
}
// if you want to go over the whole list you will have to clear the list and start over again for every element.
}
}
and here is how you could create the new list without the elements you do not want:
ArrayList<String> newLisM = new ArrayList<>();
for (int i = 0; i <booleanList.size(); i++) {
if(booleanList.get(i))
for (int j = 0; j < 3; j++) {
newLisM.add(lisM.get(i+j));
}
}

IndexOutOfBounds ArrayList error

So I have two arraylists, one multidimensional and the other just an arraylist. I keep seeming to get an out of bounds error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at is15147029.main(is15147029.java:303)
And I have no clue why, what I am doing here is imputing integers from another array into the array list. I've checked that the array is full of integers but whenever I try to add the Integers into the arraylist I get an error.
ArrayList<Integer> selOrd = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> ordIndex = new ArrayList<ArrayList<Integer>>();
for(int i = 0; i < finalCost.length; i++) {
int lowCost = 0;
if(finalCost[i] > lowCost) {
lowCost = finalCost[i];
selOrd.add(0, finalCost[i]);
}
else if(finalCost[i] <= lowCost ) selOrd.add(finalCost[i]);
}
//Get Average Fitness Cost
for(int i = 0; i < finalCost.length; i++) total = total + finalCost[i];
avg = total/(finalCost.length);
//Sort into s1, s2, s3
for(int i = 0; i < selOrd.size(); i++) {
if(selOrd.get(i) > avg) ordIndex.get(0).add(selOrd.get(i));
if(selOrd.get(i) == avg) ordIndex.get(1).add(selOrd.get(i));
if(selOrd.get(i) < avg) ordIndex.get(2).add(selOrd.get(i));
}
The error seems to occur when adding the integers to selOrd.
Ant help would be appreciated, I also have a similar problem with another array list in my code. Thank you
The problem is most likely the result of hard coded index values.
Specifically get(1) and get(2).
You MUST verify that ordIndex.size() >= 3 in
order to safely execute get(2) and
ordIndex.size() >= 2 to safely execute get(1).
Also,
pay attention to error messages.
The exception clearly states index 1, size 1.
If the size of the array is one element, then any attempt to access the second element in the array (which has an index value of 1) must fail.
At first glance in your code, I don't see you adding anything to the ordIndex ArrayList of ArrayLists, so every get call to that will throw an exception.

Are for-loops conditions able to be changed midloop?

In java programming:
I have something along the lines of
ArrayList<String> list = new ArrayList<String>();
int listSize = list.size();
for(int x = 0; x< listSize; x++){
list.remove(x);
listSize = list.size();
}
will this work well enough? or will the for loop keep running. Thanks!
I'm a bit concerned at what you're attempting to do here. Any time someone wants to remove items from a collection in a loop without using an Iterator, alarms usually go off.
So, to answer the question as stated: If you change your loop invariant, then you'll get some funky behavior. This is why it's often called an "invariant"; you don't want to change it. You're certainly welcome to, but you're playing with fire here.
But, let's assume that we have a list of 5 elements in it and we execute your code as is.
List<String> stringList = Arrays.asList("word", "another word", "let's go", "keep it up", "get moving");
int length = stringList.size();
for(int i = 0; i < length; i++) {
System.out.println(stringList.remove(i));
length = stringList.size();
}
System.out.println("done");
If you're expecting it to print out every word in the list, then think again. It will skip every element because we are changing the content of the list while iterating over it. When deleting elements from an ArrayList, the underlying implementation will shift over elements to the left in where it was deleted. So, if you delete from position 0, every element now lives to the left of its original position (so element 1 is now element 0).
A quick run-through:
First iteration, i = 0; "word" is removed. Size is changed to 4, i increases to 1.
Second iteration, i = 1; "let's go" is removed. Size is changed to 3, i increases to 2.
Third iteration, i = 2; "get moving" is removed. SIze is changed to 2, i increases to 3.
No further iteration happens as the condition is not satisfiable.
If you want to cleanly remove all items from the collection without printing them out, then ArrayList#clear() is what you're looking for. If you want to remove elements one at a time, then use an Iterator instead:
List<String> stringList = new ArrayList<>(Arrays.asList("word", "another word", "let's go", "keep it up", "get moving"));
for(Iterator<String> stringIterator = stringList.iterator(); stringIterator.hasNext(); ) {
System.out.println(stringIterator.next());
stringIterator.remove();
}
System.out.println("done");
The loop won't keep running and it will end without any exception. But the result may not what you expect.
Besides "ArrayList#clear()" or Iterator way to remove all elements from one array. You can also try below codes, just remove "x++" from your loop condition.
ArrayList<String> list = new ArrayList<String>();
int listSize = list.size();
for(int x = 0; x< listSize;){
list.remove(x);
listSize = list.size();
}
Why not do it in a "while" loop?
ArrayList<String> list = new ArrayList<String>();
int listSize = list.size();
while(list.size() != 0){
list.remove(x);
}
Technically, the computer science course would likely tell you to do it something like this:
public void solve() {
ArrayList<String> list = new ArrayList<String>();
Iterator iter = list.iterator();
while(iter.hasNext()) {
System.out.println("Next value is: " + iter.next());
iter.remove();
}
}

ArrayList of integer arrays

I'm trying to write a simple game where an enemy chases the player on a grid. I'm using the simple algorithm for pathfinding from the Wikipedia page on pathfinding. This involves creating two lists with each list item containing 3 integers. Here's test code I'm trying out to build and display such a list.
When I run the following code, it prints out the same numbers for each array in the ArrayList. Why does it do this?
public class ListTest {
public static void main(String[] args) {
ArrayList<Integer[]> list = new ArrayList<Integer[]>();
Integer[] point = new Integer[3];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//Added this line to confirm that Integer[] point is actually
//being filled with 3 random ints.
System.out.println(point[0] + "," + point[1] + "," + point[2]);
}
System.out.println();
//My current understanding is that this section should step through
//ArrayList list and retrieve each Integer[] point added above. It runs, but only
//the values of the last Integer[] point from above are displayed 10 times.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
}
First of all, several of the other answers are misleading and/or incorrect. Note that an array is an object. So you can use them as elements in a list, no matter whether the arrays themselves contain primitive types or object references.
Next, declaring a variable as List<int[]> list is preferred over declaring it as ArrayList<int[]>. This allows you to easily change the List to a LinkedList or some other implementation without breaking the rest of your code because it is guaranteed to use only methods available in the List interface. For more information, you should research "programming to the interface."
Now to answer your real question, which was only added as a comment. Let's look at a few lines of your code:
Integer[] point = new Integer[3];
This line creates an array of Integers, obviously.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//...
}
Here you assign values to the elements of the array and then add a reference to the array to your List. Each time the loop iterates, you assign new values to the same array and add another reference to the same array to the List. This means that the List has 10 references to the same array which has been repeatedly written over.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
Now this loop prints out the same array 10 times. The values in the array are the last ones set at the end of the previous loop.
To fix the problem, you simply need to be sure to create 10 different arrays.
One last issue: If you declare it as Iterator<Integer[]> it (or Iterator<int[]> it), you do not need to cast the return value of it.next(). In fact this is preferred because it is type-safe.
Finally, I want to ask what the ints in each array represent? You might want to revisit your program design and create a class that holds these three ints, either as an array or as three member variables.
I would highly recommend to enclose the integer array of 3 numbers into a meaningful class, that would hold, display and control an array of 3 integers.
Then in your main, you can have an growing ArrayList of objects of that class.
You have an extra ) here:
element = (int[])it.next()); //with the extra parenthesis the code will not compile
should be:
element = (int[])it.next();
Besides the problem in the other answer, you cal it.next() two times, that cause the iterator move forward two times, obviously that's not what you want. The code like this:
element = (int[])it.next());
String el = (String)element;
But actually, I don't see you used el. Although it's legal, it seems meaningless.

Java Array Creation and Array Name Change

Can you create a line of code, within a while-loop, that will create a new array AND change the array's name with each iteration of the while loop?
Example:
int size = 10;
int name_count = 1;
while(size <= 100)
{
//name_count is changing the name of the array by calling it
// "array1", "array2", etc...
//I know this may not be correct code for changing the name of
// the array, but it is suppose to get the point across.
int[] array(name_count) = new int[size];
for (int i = 0; i <= size; i++)
{ /* Adding numbers to an array */ }
size = size + 5;
name_count++;
}
Identifier names need to be defined at compile time. So you can't explicitly use a different variable name on each iteration of the loop.
Another problem with your pseudo-code is that, if the array were to be declared inside the loop, it would fall out of scope when the loop completes, so there wouldn't be much point.
To do something like this you need to use some collection to hold the arrays, and it would be easier to make them explicit objects instead of just arrays. Something like:
List<List<Integer>> listOfArrays = new ArrayList<List<Integer>>();
while (size <= 100) {
List<Integer> listOfNumbers = new ArrayList<Integer>(size);
/* insert loop here to add numbers to listOfNumber */
size += 5;
name_count += 1;
}
Then you can access each list of numbers using an index into listOfArrays -- equivalent to naming each one with the index, but handled at runtime instead of compile time.
You cannot change the array's name, It will just re-declare the array with each successful loop. (It will be a new blank array.) I think what you are looking for is a two dimensional array.
int[][] myArray = new int[3][3];

Categories