#java
#java
Вопрос:
Я получаю OutOfMemoryError и другие ошибки ArrayList при попытке удалить определенные элементы из ArrayList, которые могут содержать этот элемент более одного раза.
Я попытался выполнить ручной линейный поиск, удалив индексы, которые содержат указанный элемент, но также не смог заставить его работать, так как int i в цикле не будет равен 0 после первого цикла (я настроил оператор if, который присвоил бы i значение 0 в самом начале).начало цикла, если выполнено).
ArrayList<String> s = new ArrayList<String> (); /* List which will have some of its elements removed */
ArrayList<String> rem = new ArrayList<String> (); /* List containing the elements which will be removed */
ArrayList<Boolean> bool = new ArrayList<Boolean> (); /* List which will indicate if the removal of an element taken place in the previous loop */
/**/
s.add("hello");
s.add("hello");
s.add("your");
s.add("hi");
s.add("there");
s.add("hello");
/**/
rem.add("hello");
rem.add("hi");
/**/
int len=s.size();
/*loop for bool*/
for (int j=0; j<len; j) {
/* loop for rem */
for (int i=0; i<rem.size(); i) {
if (j>=1) {
if (bool.get(j-1)==true) i=0; /* If an element (from rem) had been removed from s in the previous loop, then it will continue looking for looking for that same element (from rem) until it has removed all instances of it. Then it moves to the next element in rem and removes those elements from s and so on. **/
}
if (s.contains(rem.get(i))) {
s.remove(rem.get(i));
bool.add(true);
}
else bool.add(false);
}
}
/* prints ArrayList<String> s after it has been through the removal process */
for (int i=0; i<s.size(); i) {
System.out.println(s.get(i));
}
Комментарии:
1. Вы могли бы использовать
Set
, чтобы удалить элементы, встречающиеся более одного раза.
Ответ №1:
Для этого есть 2 способа:
- Вы можете выполнить обратную итерацию:
ArrayList<String> s = new ArrayList<>();
s.add("hello");
// add more Strings...
ArrayList<String> rem = new ArrayList<>();
rem.add("hello");
// add more Strings to remove...
for (int i = s.size() - 1; i >= 0; i ) {
if (rem.contains(s.get(i)) {
s.remove(i);
}
}
- Использование removeAll:
ArrayList<String> s = new ArrayList<>();
s.add("hello");
// add more Strings...
ArrayList<String> rem = new ArrayList<>();
rem.add("hello");
// add more Strings to remove...
s.removeAll(rem);
Ответ №2:
Лучшим вариантом было бы использовать Set
ArrayList<String> s = new ArrayList<String> ();
s.add("hello");
s.add("hello");
s.add("your");
s.add("hi");
s.add("there");
s.add("hello");
Set<String> set=new HashSet<>(s);
System.out.println(set);
Ответ №3:
Это попадет в dead
круг "if (bool.get(j-1)==true) i=0"
из-за, потому что это всегда так i=0
.
Комментарии:
1. По этой причине я создал внешний цикл специально для bool. Идея заключалась в том, что это создало бы отслеживание для bool для каждого цикла. Будет ли причина, по которой это не сработает, в том, что этот цикл (с j) находится за пределами внутреннего цикла (с i), и он никогда не будет проходить до завершения внутреннего цикла?
Ответ №4:
Вам не хватает памяти, когда вы добавляете в нее новый элемент bool
из-за этой строки:
i = 0; /* If an element (from rem) had been removed from s in the previous loop, then it will continue looking for looking for that same element (from rem) until it has removed all instances of it. Then it moves to the next element in rem and removes those elements from s and so on. **/
Вы устанавливаете значение 0 для своей переменной итерации. Как следствие, эта строка: else bool.add(false)
попадает слишком много раз. До тех пор, пока я не прекратил попытки, он был сбит (и, следовательно, имел такое количество элементов): 88 раз.
Это, очевидно, неправильно.