1

I want to delete specified data in an arraylist from another class based on what the user input so when the user input Rice, the data with 'Rice' in it will be deleted this is the code so far

the data is stored in ArrayList rm in a subclass named RegularMenu.

ArrayList<RegularMenu> rm = new ArrayList<RegularMenu>();

Quiz1(){
    int input;
        do{
            System.out.println("1. Add Regular Menu");
            System.out.println("2. Add Special Menu");
            System.out.println("3. Show All Menu");
            System.out.println("4. Delete Regular Menu");
            System.out.println("5. Delete Special Menu");
            System.out.println("6. Exit" + "\n"); 

            System.out.print("Choice [1-6] ");
            Scanner s = new Scanner(System.in);
            input = s.nextInt();

            if (input == 1 ){

                String code, name;
                int price;

                System.out.println("Add Regular Menu");
                System.out.print("Input Menu Code [R...]: ");
                s.nextLine();
                code = s.nextLine();

                System.out.print("Input Menu Name [5-20]: ");
                name = s.nextLine();

                System.out.print("Input Menu Price [10000-130000]: ");
                price = s.nextInt();

                rm.add(new RegularMenu(code, name, price));
            }

            else if (input == 2){

            }

            else if (input == 3){

            }

            else if (input == 4){


                System.out.println("Input menu code you want to delete");
                String a = s.nextLine();

                for(int i=0;i<rm.size();i++){
                    if(a == rm.get(i).getCode()){
                        String code = rm.get(i).getCode();
                        a = code;
                        rm.remove(a);
                    }

                }

            }

            else if (input == 5){

            }
        }while(input != 6);
}

i can add the data, but when try to remove it, the error occurred. Let me know if I'm not clear enough.

  • 1
    First , `a == rm.get(i).getCode()` is not [How do I compare strings in Java?](https://stackoverflow.com/q/513832/4391450). Then, you already have the index of the item (`i`), so remove by index, not by value. For information, you should use an iterator for that. – AxelH May 22 '18 at 10:41
  • `if (a.equals(rm.....))` should do the trick. There might be some problems with concurrent modifications, you'll see. – Tamas Rev May 22 '18 at 10:41
  • This question leaves some ambiguity and makes it hard to see where your problem might possibly be. Showing the code for RegularMenu and the definition of getCode() could help, as could making a https://stackoverflow.com/help/mcve – Ryan Leach May 22 '18 at 10:51
  • In the future, try to propose a [mcve] instead. There is a lot of "noise" in that code that isn't necessary. – AxelH May 22 '18 at 11:04

5 Answers5

2

The problem is that you are using List.remove(Object) wrong instead of List.remove(int).

List.remove(Object)

boolean remove(Object o)

Removes the first occurrence of the specified element from this list, if it is present (optional operation). [...] More formally, removes the element with the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))) [...]

Trying to remove a RegularMenu with a String instance won't work because a String instance can't compare itself with a RegularMenu, so it will never be equivalent. (It will use String.equals(RegularMenu) method to find where is the instance to remove.

If you want to use List.remove(Object), pass the instance itself :

rm.remove(rm.get(i));

Note:

  1. that this will remove the first occurrence only, so if you have two "equivalent" instances, only the first one will be removed.
  2. List.remove(Object) will search for the index where the instance passed is using Object.equals to remove by index. But in your case you already did the job with if(a == rm.get(i).getCode()) (incorrectly, see "String comparison"),

List.remove(int)

E remove(int index)

Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their indices) [...]

Since you know the index, you can use rm.remove(i) (List.remove(int)) to remove the value at the current index.

Careful with the index that way, the right part of the list with shift on the left. See Lajos Arpad's answer for more information

Iterator

Another solution to remove items from an ArrayList is to use the iterator. You get the Iterator and iterate every items in it. Then if one match you call Iterator.remove to remove properly the item. You can even stop the loop if you only want to remove one item

Sample data :

List<String> datas = new ArrayList<>();
datas.add("foo");
datas.add("bar");
datas.add("bar");
datas.add("foo");
datas.add("bar");
datas.add("bar");
    

Code :

Iterator<String> it = datas.iterator();
String s;
while(it.hasNext()){
    s = it.next();
    if("foo".equals(s)){
        it.remove();
    }
}

System.out.println(datas);

[bar, bar, bar, bar]

I precise using ArrayList because some Collection don't implements the method remove for the Iterator giving an Exception.

Predicate - removeIf

Since Java 8, Collection.removeIf exists and allows you to do a quicker solution (using the same sample data) :

final String a = "foo";
datas.removeIf(s -> a.equals(s));

System.out.println(datas);

[bar, bar, bar, bar]

It will iterate and check for each instance of RegularMenu in it if the Predicate passed will be true, if so, the item will be removed.


String comparison

Also, note the comparison "foo".equals(s) instead of "foo" == s.
More information in How do I compare strings in Java?

Community
  • 1
  • 1
AxelH
  • 14,325
  • 2
  • 25
  • 55
1

You can remove elements from List by index

for(int i=rm.size()-1; i>=0; i--) {
    // you are deleting elements from the list while iterating,
    // thus it is better to iterate backwards (rm.size()..0):

    if(a.trim().equals(rm.get(i).getCode().trim())) {
        rm.remove(i);
    }
}

Note: when you delete an element under index i, all elements to the right (i+1, ...) will be moved to the left for one position.

Thus, when iterating from left to right and deleting elements, you will be messing with indices.
On the other hand, when you are iterating from right to left and deleting something at position i, all elements to to right will still be moved one position to the left, but It does not matter for you, because you will not iterate on them.

aaaaBcccc    ->  aaaacccc
^   ^            ^   ^ 
0.. i            0.. i
Viacheslav Shalamov
  • 4,149
  • 6
  • 44
  • 66
1

You can iterate your array list with a loop and remove all matches:

for (int i = 0; i < yourArrayList.size(); i ++) {
    if(a.equals(rm.get(i).getCode())){
        yourArrayList.remove(i--);
    }
}

Your mistake was that you tried to remove a from the ArrayList using remove, but remove expects an int, representing the index to be removed. In my code notice that I am decrementing i after removing to be able to remove consequent matches.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0
for(int i=0;i<rm.size();i++) {
    if(a.trim().equals(rm.get(i).getCode())) {
        rm.remove(i);
        break;
    }
 }

In the list, you can remove elements by using index.

Sree
  • 374
  • 2
  • 10
  • This way you can delete only one element without messing with indices. You prudently added `break`, but what if we want to delete multiple elements? – Viacheslav Shalamov May 22 '18 at 10:48
  • Yes, I added break because code might be unique for each item. If it is unique, this works effectively. – Sree May 22 '18 at 10:58
  • may i know what's trim usage in general and in this code ? – Kevin Guswanto May 23 '18 at 04:53
  • trim() will remove the extra spaces before and after the string.. For example if we have a string " hello ", if we use trim() for this, then we will get "hello" – Sree May 23 '18 at 07:13
-1

Find below code :

               for(RegularMenu regularMenu:rm){
                     if(a.equalsIgnoreCase(regularMenu.getCode())){
                           rm.remove(regularMenu);
                           break;
                        }
  • You can't remove items for a list that is being iterated with a for iterative loop. > `ConcurrentModificationException` – AxelH May 22 '18 at 10:56
  • PS: didn't noticed the `break` but this is assuming only one occurrence exist, giving an hiding problem if multiple occurrence should be removed later. – AxelH May 22 '18 at 11:03