[JAVA] Be careful when deleting multiple elements from an array etc. with a for statement

Introduction

It outputs the algorithmic things learned while repairing the system at work instead of memos. Originally it was C #, but since I don't have a C # environment at home, I write it in Java.

Status

Originally, it wasn't an array, it was a little more complicated like an array, and there were many elements inside, but to put it simply, ** product data ** (name, price, etc.) and its ** product inventory * There was an array that had a lot of *.

Launcher.java


ArrayList<Object[]> syohinList = new ArrayList<Object[]>();

//Product name Stock quantity
Object[] syohin1 = {"Apple",  5};
Object[] syohin2 = {"Grape",  20};
Object[] syohin3 = {"Mandarin orange",  0};
Object[] syohin4 = {"Kiwi",  10};
Object[] syohin5 = {"banana",  15};

syohinList.add(syohin1);
syohinList.add(syohin2);
syohinList.add(syohin3);
syohinList.add(syohin4);
syohinList.add(syohin5);

//Check the remaining stock quantity of the product
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println(syohinList.get(i)[0] + "Residual inventory:" + syohinList.get(i)[1]);
}
//Output result
Residual stock of apples:5
Grape stock:20
Mandarin orange remaining inventory:0
Kiwi residual inventory:10
Banana stock:15

So, one of my tasks was to implement a ** function to delete products with 0 remaining inventory from the array **.

What i did

I wrote the code safely by repeating the for statement for the number of times of the array and deleting it from the array if the remaining inventory is 0.

Launcher.java


ArrayList<Object[]> syohinList = new ArrayList<Object[]>();

//Product name Stock quantity
Object[] syohin1 = {"Apple",  5};
Object[] syohin2 = {"Grape",  20};
Object[] syohin3 = {"Mandarin orange",  0};
Object[] syohin4 = {"Kiwi",  10};
Object[] syohin5 = {"banana",  15};

syohinList.add(syohin1);
syohinList.add(syohin2);
syohinList.add(syohin3);
syohinList.add(syohin4);
syohinList.add(syohin5);

for ( int i = 0; i < syohinList.size(); ++i ) {
    //If the product inventory is 0, delete it from the array
    if ((int)syohinList.get(i)[1] == 0) {
        syohinList.remove(i);
    }
}

//Check the remaining stock quantity of the product
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println(syohinList.get(i)[0] + "Residual inventory:" + syohinList.get(i)[1]);
}

//Output result
Residual stock of apples:5
Grape stock:20
Kiwi residual inventory:10
Banana stock:15

Yeah, it's gone. But actually there is a problem.

Problems that occurred

This method is to check the element from the 0th and delete it from the element if the condition is met (if the inventory is 0), but ** Under certain conditions, deletion omission occurs. ** Specifically ** When elements that satisfy the deletion conditions come in succession. ** **

Launcher.java


ArrayList<Object[]> syohinList = new ArrayList<Object[]>();

//Product name Stock quantity
Object[] syohin1 = {"Apple",  5};
Object[] syohin2 = {"Grape",  20};
Object[] syohin3 = {"Mandarin orange",  0}; //Target to be deleted
Object[] syohin4 = {"Kiwi",  0}; //Target to be deleted
Object[] syohin5 = {"banana",  15};

syohinList.add(syohin1);
syohinList.add(syohin2);
syohinList.add(syohin3);
syohinList.add(syohin4);
syohinList.add(syohin5);

for ( int i = 0; i < syohinList.size(); ++i ) {
    //If the product inventory is 0, delete it from the array
    if ((int)syohinList.get(i)[1] == 0) {
        syohinList.remove(i);
    }
}

//Check the remaining stock quantity of the product
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println(syohinList.get(i)[0] + "Residual inventory:" + syohinList.get(i)[1]);
}

//Output result
Residual stock of apples:5
Grape stock:20
Kiwi residual inventory:0 //It hasn't disappeared for some reason
Banana stock:15

The oranges are gone, but the kiwi isn't.

Cause

** The cause was that the element was deleted and the subsequent elements were shifted forward. ** **

Launcher.java


ArrayList<Object[]> syohinList = new ArrayList<Object[]>();

//Product name Stock quantity
Object[] syohin1 = {"Apple",  5};
Object[] syohin2 = {"Grape",  20};
Object[] syohin3 = {"Mandarin orange",  0}; //Target to be deleted
Object[] syohin4 = {"Kiwi",  0}; //Target to be deleted
Object[] syohin5 = {"banana",  15};

syohinList.add(syohin1);
syohinList.add(syohin2);
syohinList.add(syohin3);
syohinList.add(syohin4);
syohinList.add(syohin5);

//Check the remaining stock quantity of the product
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println("Array" + i + " " + syohinList.get(i)[0] + " " + "Residual inventory:" + syohinList.get(i)[1]);
}

System.out.println("------------------------"); //Separator (to make it easier to see)

for ( int i = 0; i < syohinList.size(); ++i ) {
    //If the product inventory is 0, delete it from the array
    if ((int)syohinList.get(i)[1] == 0) {
        syohinList.remove(i);
    }
}

//Reconfirm the number of remaining products in stock
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println("Array" + i + " " + syohinList.get(i)[0] + " " + "Residual inventory:" + syohinList.get(i)[1]);
}

//Output result
Array 0 Apples Remaining inventory:5
Array 1 Grape stock:20
Array 2 mandarin orange remaining inventory:0
Array 3 Kiwi Remaining Inventory:0
Array 4 Banana Remaining Inventory:15
------------------------
Array 0 Apples Remaining inventory:5
Array 1 Grape stock:20
Array 2 Kiwi Remaining Inventory:0 //The oranges disappeared and slipped
Array 3 Banana Remaining Inventory:15 //The oranges disappeared and slipped

If you take a closer look at each loop,

//First loop: array[0]To find out
Array[0]Residual stock of apples:5    //Since the remaining inventory is not 0, do not delete it
Array[1]Grape stock:20   //I haven't checked it yet
Array[2]Mandarin orange remaining inventory:0    //I haven't checked it yet
Array[3]Kiwi residual inventory:0    //I haven't checked it yet
Array[4]Banana stock:15   //I haven't checked it yet
//Second loop: array[1]To find out
Array[0]Residual stock of apples:5    //Examined
Array[1]Grape stock:20   //Since the remaining inventory is not 0, do not delete it
Array[2]Mandarin orange remaining inventory:0    //I haven't checked it yet
Array[3]Kiwi residual inventory:0    //I haven't checked it yet
Array[4]Banana stock:15   //I haven't checked it yet

The problem starts here.

//Third loop: array[2]To find out
Array[0]Residual stock of apples:5    //Examined
Array[1]Grape stock:20   //Examined
Array[2]Mandarin orange remaining inventory:0    //Since the remaining inventory is 0, delete it.
Array[3]Kiwi residual inventory:0    //I haven't checked it yet
Array[4]Banana stock:15   //I haven't checked it yet

This deletes the elements of array [2] and shifts the elements (kiwi) of array [3] to array [2] and the elements of array 4 to array [3].

//Third loop: array[2]Investigated
Array[0]Residual stock of apples:5    //Examined
Array[1]Grape stock:20   //Examined
Array[2]Kiwi residual inventory:0    //I haven't checked it yet
Array[3]Banana stock:15   //I haven't checked it yet

That's right, in the current situation, I searched up to array [2], but ** that array [2] contains elements that I haven't checked yet. ** **

//Fourth loop: array[3]To find out
Array[0]Residual stock of apples:5    //Examined
Array[1]Grape stock:20   //Examined
Array[2]Kiwi residual inventory:0    //I didn't check it, but it was skipped as a result
Array[3]Banana stock:15   //Since the remaining inventory is not 0, do not delete it

It feels like it's gone well between the loops. When I was wondering what happened, my senior advised me to deduct from the maximum value and investigate from the opposite direction. I see. It's like I've done it in class a long time ago. However, after that, due to a design change, it was not necessary to use for after all, so I did not implement it. However, I was curious, so I thought about the movement at home.

solution

I wrote this code.

Launcher.java


ArrayList<Object[]> syohinList = new ArrayList<Object[]>();

//Product name Stock quantity
Object[] syohin1 = {"Apple",  5};
Object[] syohin2 = {"Grape",  20};
Object[] syohin3 = {"Mandarin orange",  0}; //Target to be deleted
Object[] syohin4 = {"Kiwi",  0}; //Target to be deleted
Object[] syohin5 = {"banana",  15};

syohinList.add(syohin1);
syohinList.add(syohin2);
syohinList.add(syohin3);
syohinList.add(syohin4);
syohinList.add(syohin5);

//Examine from behind
for ( int i = syohinList.size() - 1; i >= 0; --i ) {
    //If the product inventory is 0, delete it from the array
    if ((int)syohinList.get(i)[1] == 0) {
        syohinList.remove(i);
    }
}

//Check the remaining stock quantity of the product
for ( int i = 0; i < syohinList.size(); ++i ) {
    System.out.println("Array" + i + " " + syohinList.get(i)[0] + " " + "Residual inventory:" + syohinList.get(i)[1]);
}

Until now, I searched from the front of the array (ascending order), but this time I changed it to ** looking from the back of the array (descending order) **.

Array 0 Apples Remaining inventory:5
Array 1 Grape stock:20
Array 2 Banana Remaining Inventory:15

Yeah, it looks like it's gone well. Looking at the movement again loop by loop,

//First loop: array[4]To find out
Array[0]Residual stock of apples:5    //I haven't checked it yet
Array[1]Grape stock:20   //I haven't checked it yet
Array[2]Mandarin orange remaining inventory:0    //I haven't checked it yet
Array[3]Kiwi residual inventory:0    //I haven't checked it yet
Array[4]Banana stock:15   //Since the remaining inventory is not 0, do not delete it
//Second loop: array[3]To find out
Array[0]Residual stock of apples:5    //I haven't checked it yet
Array[1]Grape stock:20   //I haven't checked it yet
Array[2]Mandarin orange remaining inventory:0    //I haven't checked it yet
Array[3]Kiwi residual inventory:0    //Deleted because the remaining inventory is 0
Array[4]Banana stock:15   //Examined

The element (kiwi) of the array [3] is deleted and the element (banana) of the array [4] is newly put in the array [3], but there is no problem because it is in descending order.

//Third loop: array[2]To find out
Array[0]Residual stock of apples:5    //I haven't checked it yet
Array[1]Grape stock:20   //I haven't checked it yet
Array[2]Mandarin orange remaining inventory:0    //Deleted because the remaining inventory is 0
Array[3]Banana stock:15   //Examined

The element (mandarin orange) of the array [2] is deleted and the element (banana) of the array [3] is newly put in the array [2], but there is no problem because it has already been investigated.

//Fourth loop: array[1]To find out
Array[0]Residual stock of apples:5    //I haven't checked it yet
Array[1]Grape stock:20   //Since the remaining inventory is not 0, do not delete it
Array[2]Banana stock:15   //Examined
//5th loop: array[0]To find out
Array[0]Residual stock of apples:5    //Since the remaining inventory is not 0, do not delete it
Array[1]Grape stock:20   //Examined
Array[2]Banana stock:15   //Examined

It is like this. I think it's all okay in terms of operation. (Perhaps)

in conclusion

Perhaps it's a fairly basic idea of the algorithm. I feel like I've heard it a long time ago. However, recently I've been doing Ruby and relying on convenient methods, so I thought it was important to train this way of thinking.

reference

https://www.javadrive.jp/start/for/index2.html http://d.hatena.ne.jp/nattou_curry_2/20090726/1248600833

Recommended Posts

Be careful when deleting multiple elements from an array etc. with a for statement
Swift: A trap when setting multiple initial elements in an array
[Java] How to turn a two-dimensional array with an extended for statement
[Technical memo] Things to be careful of from an engineer's point of view when creating a view
Be careful when using multiple articles
When seeking multiple in a Java array
[Ruby] Get unique elements from an array
Be careful when using rails_semantic_logger with unicorn
[Ruby] Calculation by extracting elements from an array
[Java] Get a random value from an array
A program that outputs a number greater than or equal to the input integer and a number less than the input integer from an array with 50 elements.
When deleting a record with MySQL workbench, javax.persistence.EntityNotFoundException occurs
How to use an array for a TreeMap key
[Java basics] Let's make a triangle with a for statement
How to output standard from an array with forEach
[Ruby] How to extract a specific value from an array under multiple conditions [select / each]
(For myself) Build an IDE that you can touch from a browser with docker (trial)