Удалить указанный объект в arraylist из другого класса в java

Kevin Guswanto спросил: 28 апреля 2018 в 08:57 в: java

Я хочу удалить указанные данные в arraylist из другого класса, основываясь на том, что пользователь вводит / когда пользователь вводит Rice, данные с "Rice" в нем будут удалены. Это код до сих пор

данные хранятся в ArrayList rm в подклассе с именем 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);
}

Я могу добавить данные, но при попытке удалить его произошла ошибка. Сообщите мне, m недостаточно ясно.

5 ответов

Есть решение
Lajos Arpad ответил: 28 апреля 2018 в 09:14

Вы можете перебирать список массивов с помощью цикла и удалять все совпадения:

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

Ваша ошибка заключалась в том, что вы пытались выполнить remove a из ArrayList, используя remove, но remove ожидает int, представляющий индекс, который нужно удалить. В моем уведомлении кода, что я уменьшаю i после удаления, чтобы иметь возможность remove последующих совпадений.

AxelH ответил: 28 апреля 2018 в 09:17
О да, я пропустил индекс, пропущенный с этой логикой!
Kevin Guswanto ответил: 28 апреля 2018 в 03:12
это то, что я могу понять легко. Другая ответная работа тоже, но я пытаюсь использовать ответ, основываясь на том, чему научил меня преподаватель, спасибо
Lajos Arpad ответил: 29 апреля 2018 в 06:25
@KevinGuswanto, пожалуйста.
AxelH ответил: 28 апреля 2018 в 09:47

Проблема в том, что вместо List.remove(Object) вы используете List.remove(int).

boolean remove(Object o)

Удаляет первое вхождение указанного элемента из этого списка, если оно присутствует (дополнительная операция). [...] Более формально удаляет элемент с самым низким индексом i таким образом, что (o==null ? get(i)==null : o.equals(get(i))) [...]

Попытка удалить RegularMenu с экземпляром String не будет работать, потому что экземпляр String не может сравниться с RegularMenu, поэтому он никогда не будет эквивалентен. (Он будет использовать метод String.equals(RegularMenu), чтобы найти, где удалить экземпляр.

Если вы хотите использовать List.remove(Object), пропустите сам экземпляр:

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

Примечание:

  1. , что это удалит только первое вхождение, поэтому, если у вас есть два "эквивалентных" экземпляра, будет удален только первый.
  2. List.remove(Object) будет искать индекс, в котором экземпляр прошел, используя Object.equals для удаления по индексу. Но в вашем случае вы уже выполнили задание с помощью if(a == rm.get(i).getCode()) (неверно, см. " Сравнение строк "),

E remove(int index)

Удаляет элемент в указанной позиции в этом списке (необязательная операция). Сдвигает любые последующие элементы влево (вычитает один из их индексов) [...]

Поскольку вы знаете индекс, вы может использовать rm.remove(i) (List.remove(int)), чтобы удалить значение в текущем индексе.

Осторожно, указав этот путь, правая часть списка со сдвигом влево. См. Ответ Лажоса Арпада для получения дополнительной информации

Другим решением для удаления элементов из ArrayList является использование итератора. Вы получаете Iterator и повторяете все элементы в нем. Затем, если вы соответствуете, вы вызываете Iterator.remove, чтобы правильно удалить элемент. Вы даже можете остановить цикл, если хотите удалить только один элемент

Пример данных:

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

Код:

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]

Я точно использую ArrayList, потому что некоторые Collection не реализуют метод remove для Iterator, дающий Exception.

Так как Java 8, Collection.removeIf существует и позволяет вам для выполнения более быстрого решения (с использованием тех же данных образца):

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

[bar, bar, bar, bar]

Он будет перебирать и проверять каждый экземпляр RegularMenu в нем, если Predicate прошел true, если это так, элемент будет удален.


Также обратите внимание на сравнение "foo".equals(s) вместо "foo" == s.
Дополнительная информация в Как сравнить строки в Java ?

Viacheslav Shalamov ответил: 28 апреля 2018 в 10:07

Вы можете удалить элементы из списка по индексу

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);
    }
}

Примечание: при удалении элемента под индексом i все элементы справа (i+1, ...) будет перемещен влево для одной позиции.

Таким образом, при повторении слева направо и удалении элементов вы будете возиться с индексами.
С другой стороны, когда вы повторяются справа налево и удаляют что-то в позиции i, все элементы вправо все равно будут перемещены на одну позицию влево, но для вас это не важно, потому что вы не будете перебирать их.

aaaaBcccc    ->  aaaacccc
^   ^            ^   ^ 
0.. i            0.. i
AxelH ответил: 28 апреля 2018 в 09:20
Вы должны объяснить, почему вы перебираете список назад, это очень важно в процессе удаления!
Viacheslav Shalamov ответил: 28 апреля 2018 в 10:08
Добавлено некоторое объяснение. Это достаточно просто?
Srivenu ответил: 28 апреля 2018 в 09:04
for(int i=0;i<rm.size();i++) {
    if(a.trim().equals(rm.get(i).getCode())) {
        rm.remove(i);
        break;
    }
 }

В списке вы можете удалить элементы с помощью индекса.

Viacheslav Shalamov ответил: 28 апреля 2018 в 09:08
Таким образом, вы можете удалить только один элемент, не входя в индексы. Вы осторожно добавили break, но что, если мы хотим удалить несколько элементов?
Srivenu ответил: 28 апреля 2018 в 09:18
Да, я добавил перерыв, потому что код может быть уникальным для каждого элемента. Если он уникален, это работает эффективно.
Kevin Guswanto ответил: 28 апреля 2018 в 03:13
могу ли я знать, что такое обрезание в общем и в этом коде?
Srivenu ответил: 28 апреля 2018 в 05:33
trim () удалит лишние пробелы до и после строки. Например, если у нас есть строка "hello", если мы используем trim () для этого, тогда мы получим "привет",
shamsher Khan ответил: 28 апреля 2018 в 09:15

Найдите ниже код:

               for(RegularMenu regularMenu:rm){
                     if(a.equalsIgnoreCase(regularMenu.getCode())){
                           rm.remove(regularMenu);
                           break;
                        }
AxelH ответил: 28 апреля 2018 в 09:16
Вы не можете удалить элементы для списка, который выполняется с помощью итеративного цикла. & GT; ConcurrentModificationException
AxelH ответил: 28 апреля 2018 в 09:23
PS: не заметил break, но предполагается, что существует только одно вхождение, что дает проблему сокрытия, если несколько случаев следует удалить позже.