Methods and precautions of removing elements in Java collection

Time:2020-11-25

1. Preface

Operation set is a thing that Java programmers repeat almost every day. Today, let’s look at ways to remove elements from the Java collection. I’ve built a simple collection, and we’ll take this as an example to explore.


 List<String> servers = new ArrayList<>();
 servers.add("Felordcn");
 servers.add("Tomcat");
 servers.add("Jetty");
 servers.add("Undertow");
 servers.add("Resin");

2. For loops do not necessarily remove elements from a collection

Let’s use the traditional foreach loop to remove the fake server that starts with F, but you will find that this operation raises a concurrenctmodificationexception.

//Never use a wrong demonstration
 for (String server : servers) {
 if (server.startsWith("F")) {
 servers.remove(server);
 }
 }

Can’t a for loop remove elements? Of course not! If we can determine the index of the element that needs to be removed, it is OK.

//This way is feasible
 for (int i = 0; i < servers.size(); i++) {
 if (servers.get(i).startsWith("F")) {
 servers.remove(i);
 }
}

But I’ve only demonstrated ArrayList in this way. Other types are not strictly tested and left to you to explore.

3. Iterator can delete elements in the collection

In the traditional way, we use iterator to ensure the deletion of elements


 Iterator<String> iterator = servers.iterator();

 while (iterator.hasNext()) {
  String next = iterator.next();
  if (next.startsWith("F")) {
  iterator.remove();
  }
 }

4. Disadvantages of traversing and deleting elements

  • We need to traverse each element of the collection and assert them, even if you delete one.
  • Although we can delete specific elements iteratively, the operation is cumbersome, and there are potential concurrent modificationexception exceptions depending on the collection type.
  • According to the different data structures, the time complexity of deleting elements is greatly different. For example, array structure ArrayList is not as fast as linked list structure in deleting elements.

5. Delete new set elements

Java 8 provides a new set manipulation API and stream to help us solve this problem. I have introduced the Java 8 stream API in previous articles. If you are interested, you can take a look.

5.1 Collection.removeIf()

New collection API removeif (predict <? Super E > filter). The API provides a more concise way to delete elements using predicate, so we can implement the initial requirements more concisely:

servers.removeIf(s-> s.startsWith("F"));

At the same time, according to the test, the performance of ArrayList and LinkedList is close. This method is recommended.

5.2 stream implementation remove element

Different from all the above removal operations, in fact, no operation will change the stream source. We only use the stream API to operate the copy of the data source. It follows the life cycle of data source > intermediate operation > induction termination. Let’s look at how to use stream to achieve our intention.

5.2.1 through filter assertion

We can use stream’s filter assertion. Filter assertion will aggregate the stream elements that conform to the assertion into a new stream, and then summarize them. Therefore, we can write as follows:

//Different from the above, the assertion in this method is a negation operation.
List<String> newServers = servers.stream().filter(s -> !s.startsWith("F")).collect(Collectors.toList());

This advantage has been mentioned above, it will not affect the original data, but will generate a copy. The disadvantage is that there may be memory consumption problems.

5.2.2 pass Collectors.partitioningBy induce

This method can meet the needs, but I feel a bit opportunistic. Collectors.partitioningBy () the original intention of the method is to make two classifications. In this method, the elements that conform to the assertion and those that do not conform to the assertion are summarized into two maps with the key of true and false respectively. We can classify the elements that conform to and do not conform to the assertion. The implementation is as follows:

Map<Boolean, List<String>> f = servers.stream().collect(Collectors.partitioningBy(s -> !s.startsWith("F")));
 
 List<String> trues = f.get(Boolean.TRUE);
 System.out.println ("not beginning with F: + trues];

 List<String> falses = f.get(Boolean.FALSE);
 System.out.println "+ falls" starting with F;

Generally, this method is not recommended in this scenario and does not conform to the design intent of the API.

6. Summary

Today we’ve looked at some ways to remove elements from collections and their considerations. Hope to help you, if you have any questions, please leave me a message, small editor will reply to you in time. Thank you very much for your support to the developeppaer website!
If you think this article is helpful to you, welcome to reprint, please indicate the source, thank you!