Я изучаю ООП и наткнулся на списки массивов. Я хотел бы знать, как на самом деле работает функция remove() и каков наиболее эффективный способ ее использования.
Первый способ удалить все "ББ"
public class ArrayListTest {
public static void main(String args[]){
ArrayList<String> Alist = new ArrayList<String>();
Alist.add("AA");
Alist.add("BB");
Alist.add("AA");
Alist.add("AA");
Alist.add("AA");
Alist.add("BB");
System.out.println("Original ArrayList : " + Alist);
int n = 0 ;
for (int i = 0; i < Alist.size(); i++){
n++;
Alist.remove("BB");
}
System.out.println(n);
System.out.println("Modified ArrayList : " + Alist);
}
}
Выход
run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
4
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)
Второй способ удалить все «BB»
public class ArrayListTest {
public static void main(String args[]){
ArrayList<String> Alist = new ArrayList<String>();
Alist.add("AA");
Alist.add("BB");
Alist.add("AA");
Alist.add("AA");
Alist.add("AA");
Alist.add("BB");
System.out.println("Original ArrayList : " + Alist);
int n = 0 ;
while(Alist.contains("BB")){
n++;
Alist.remove("BB");
}
System.out.println(n);
System.out.println("Modified ArrayList : " + Alist);
}
}
Выход
run:
Original ArrayList : [AA, BB, AA, AA, AA, BB]
2
Modified ArrayList : [AA, AA, AA, AA]
BUILD SUCCESSFUL (total time: 0 seconds)
Это сбивает с толку, потому что счетчик был запущен для увеличения еще несколько раз в первом, но на самом деле он более эффективен, или «содержит ()» перебирает весь список массивов при каждой проверке оператора за сценой.
Как вы определили, какой фрагмент был более эффективным?
На самом деле, я этого не делал, и это именно то, о чем я пытаюсь спросить.. @Eran




Если вы используете Java8, все, что вам нужно, это просто:
aList.removeIf(s -> s.equals("BB"));
Или как короткий путь:
aList.removeIf("B"::equals);
Если вы заметили, таким образом не нужно проверять, существует ли элемент в списке или нет.
в качестве хорошей практики:
Alist, вместо этого используйте, например, aListВероятно, наиболее эффективный способ удаления из массива:
Alist.removeAll(Collections.singleton("BB"))
или
Alist.removeIf("BB"::equals)
Эти методы могут быть более эффективными, чем отдельные вызовы remove, поскольку фактическое удаление можно отложить до тех пор, пока не будут идентифицированы все элементы, равные "BB".
Это важно, потому что удаление элемента из ArrayList сдвигает все элементы с большим индексом «вниз на один». В худшем случае (когда все элементы списка равны тому, что вы хотите удалить), отдельные вызовы удаления списка будут квадратичными по количеству элементов списка; removeAll или removeIf будут линейными, потому что они могут сдвигать неудаленные элементы только один раз и вообще не беспокоиться о сдвиге элементов, подлежащих удалению.
Самая очевидная неэффективность первого метода заключается в том, что вы вызываете remove столько раз, сколько элементов списка, независимо от того, сколько раз элемент появляется в списке. В особенно патологическом примере у вас может быть 1 миллион элементов в списке, где ни один из них не равен "BB": вы все равно будете вызывать remove 1 миллион раз.
Самая очевидная неэффективность второго метода заключается в том, что вы вызываете contains, а затем remove. Вы ищете элемент дважды, делая это.
Более эффективным методом, но все же менее эффективным, чем два метода в начале этого ответа, было бы использование возвращаемое значение remove, которое является логическим значением, указывающим, действительно ли элемент был удален. Как только remove вернет false, нет смысла снова вызывать remove, потому что элемент не найден:
while (Alist.remove("BB")) {}
List<String> list1=new ArrayList(Arrays.asList("AA","BB","AA","AA","AA","BB"));
List<String> list2=new ArrayList();
list2=list1.stream().filter(a -> !a.equals("BB")).collect(Collectors.toList());
System.out.println(list2);
Это отлично работает! Проверьте это.