preface

The most commonly used are ArrayList and HashMap, and are frequently used for q&A during job interviews. Regardless of capacity, load factor and so on, even simple use will also encounter pits.

Remove elements

A common scenario is to go through a list and find the right conditions to delete, such as deleting all even numbers.

@Test
public void testRemove2(a){
    List<Integer> integers = new ArrayList<>(5);
    integers.add(1);
    integers.add(2);
    integers.add(2);
    integers.add(4);
    integers.add(5);

    for (int i = 0; i < integers.size(); i++) {
        if (integers.get(i)%2= =0){
            integers.remove(i);
        }
    }

    System.out.println(integers);
}Copy the code

It seems like it’s okay, so go in and ask: What was the output? Is there really no mistake in asking again? And what is the result?

  • An error
  • The result is an empty list
  • The result is [1, 2, 5]

List.remove() has two, onepublic E remove(int index), one ispublic boolean remove(Object o)What are the following results:

@Test
public void testRemove(a){
    ArrayList<Integer> integers = Lists.newArrayList(1.2.3.4);
    System.out.println(integers);
    integers.remove(1);
    System.out.println(integers);
}Copy the code
  • [1, 3, 4]

You’ll often use an arrays.aslist API, so what’s the result here:

@Test
public void testRemove3(a){
    List<String> list = Arrays.asList("a"."b");
    list.add("c");
    System.out.println(list);
}Copy the code
  • Error: Java. Lang. UnsupportedOperationException

Can we use foreach to solve our initial problem

@Test
public void testRemove4(a){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    for(String string : strings) { strings.remove(string); }}Copy the code
  • No, an error Java. Util. ConcurrentModificationException

For performance reasons, we recommend extracting the calculation of list.size

@Test
public void testRemove5(a){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    int size = strings.size();
    for (int i = 0; i < size; i++) { strings.remove(i); }}Copy the code
  • Error: Java. Lang. IndexOutOfBoundsException: Index: 2, Size: 2
  • This is a good practice, not counting size once in each loop like we did in the beginning, and you can still get an error when you run it again. This is not a mistake, but the result is not what we want.

Use Iterator to remove


@Test
public void testRemove6(a){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        strings.remove(next);
    }

    System.out.println(strings);
}Copy the code
  • Error: Java. Util. ConcurrentModificationException

What is the correct way to remove

@Test
public void testRemove7(a){
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("b");
    strings.add("c");
    strings.add("d");

    Iterator<String> iterator = strings.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        iterator.remove();
    }

    System.out.println(strings);
}Copy the code