Есть класс Alpha
, у него String name QWERTY
Есть Arraylist list
Экземпляр туда добавлен, но вернуть его не могу.
Alpha ah1 = removeAndGet("QWERTY");
Alpha removeAndGet(String name) {
Alpha temp = null;
for(Alpha element: list) {
if(element.getName().equals(name)) {
temp = list.get(list.indexOf(element));
list.remove(list.indexOf(element));
}
}
return temp;
}
Получаю:
Exception in thread "main" java.util.ConcurrentModificationException
Ни стрим , ничего не помогает. list.removeIf(o->o.equals(alpha));
это на удаление отдельно работает list.remove(list.indexOf(alpha));
и это тоже а по условию невозможно.
Изменять список внутри for-each нельзя. Можно отделить поиск от удаления через Stream API:
static Alpha removeAndGet(String name) {
//получаем первый подходящий объект
//или null, если таких нет
Alpha temp = list.stream()
.filter(a -> name.equals(a.getName()))
.findFirst()
.orElse(null);
//удаляем *ВСЕ* объекты с таким именем
list.removeIf(a -> name.equals(a.getName()));
return temp;
}
Как @Andrew Bystrov пишет в комментах, здесь будет два прохода: первый — для поиска до найденного элемента, второй — для удаления по всему списку. С помощью Optional.isPresent
можно попробовать избежать второго прохода если элемент не был найден.
Исполняемый пример (https://ideone.com/B1qski):
import java.util.*;
class Ideone {
static List<Alpha> list;
public static void main (String[] args) {
String name = "qwerty";
list = new ArrayList<>(Arrays.asList(new Alpha("foo"), new Alpha(name),
new Alpha("bar"), new Alpha("lol")));
Alpha temp = removeAndGet(name);
System.out.println(temp); //qwerty
System.out.println(list); //[foo, bar, lol]
}
static Alpha removeAndGet(String name) {
//получаем первый подходящий объект
//или null, если таких нет
Alpha temp = list.stream()
.filter(a -> name.equals(a.getName()))
.findFirst()
.orElse(null);
//удаляем *ВСЕ* объекты с таким именем
list.removeIf(a -> name.equals(a.getName()));
return temp;
}
static class Alpha {
String name;
Alpha(String name) {
this.name = name;
}
String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
}
Можно написать без Stream API, по-старому, через Iterator.remove
:
Alpha removeAndGet(String name) {
Alpha result = null;
Iterator<Alpha> iterator = list.iterator();
while(iterator.hasNext()) {
Alpha a = iterator.next();
if(name.equals(a.getName())) {
//так будет присвоен последний найденный элемент
//если важно выбрать первый, то нужно добавить проверку на null
result = a;
iterator.remove();
}
}
return result;
}
Пример: https://ideone.com/qnGQux
Надо использовать перебирание через i, foreach не предназначен для изменения списка:
Alpha removeAndGet(String name){
Alpha temp = null;
for(int i = 0; i < list.size();) {
Alpha tmp = list.remove(i);
if(tmp.getName().equals(name)) temp = tmp;
}
return temp;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Вычитанием строк назовем операцию при которой все буквы вычитаемого вычеркиваются из уменьшаемого, а если в уменьшаемом таких букв не было...
Есть приложение на Spring boot 2, в котором пользователи авторизуюца и получают access keyКлиентская часть крутится на nodejs