1. Preface
The operations collection is a Java Programmers repeat things almost every day. Today, let's study from Java Collection Method for deleting elements in. I built a simple collection, and we explored it as an example.
List<String> servers = new ArrayList<>(); servers.add("Felordcn"); servers.add("Tomcat"); servers.add("Jetty"); servers.add("Undertow"); servers.add("Resin");
2. The for loop does not necessarily remove elements from the collection
Let's use the traditional foreach Circular removal F False server at the beginning, but you will find that this operation causes ConcurrentModificationException Abnormal.
// Never use the 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 to be removed, it is OK.
// This approach is feasible for (int i = 0; i < servers.size(); i++) { if (servers.get(i).startsWith("F")) { servers.remove(i); } }
But I've only demonstrated this way so far ArrayList, other types are not strictly tested and are left to you to explore.
3. Iterator iterator can delete elements in the collection
In the traditional way, we use Iterator It can guarantee 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 element.
- Although we can delete specific elements iteratively, the operation is cumbersome and has potential problems according to different collection types ConcurrentModificationException Abnormal.
- According to different data structures, the time complexity of deleting elements is also greatly different. such as Second hand mobile game account Array structure ArrayList The speed of deleting elements is not as fast as that of linked list structure LinkedList.
5. Delete new collection elements
Java 8 Provides a new collection operation API and Stream To help us solve this problem. I have introduced it in previous articles. If you are interested, you can go and have a look.
5.1 Collection.removeIf()
new Collection Api removeIf(Predicate
filter) . Should Api Provides a more concise use Predicate (assertion) the method of deleting elements, so we can more concisely implement the starting requirements:
servers.removeIf(s-> s.startsWith("F"));
At the same time, according to the test, ArrayList and LinkedList The performance is close. This is generally recommended.
5.2 Stream implementation remove elements
Unlike all the above removal operations, none of them will change Stream Source, we just use Stream Api Copy of the operation data source. Followed Data source - > intermediate operation - > induction termination Life cycle of. Let's see how to use it Stream How to achieve our intentions.
5.2.1 implementation through filter assertion
We can use Stream of filter Assertions. filter The assertion will integrate the flow elements that meet the assertion into a new flow, and then sum them up. Therefore, we can write as follows:
// The difference from the above is that 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 induction through collectors.partitionby
Although this method can meet the needs, I feel a little opportunistic. Collectors.partitioningBy() The original intention of the method is to do secondary classification. This method will summarize the elements in the stream that meet the assertion and those that do not meet the assertion into two categories respectively key Respectively true and false of Map In, we can classify the consistent and inconsistent element sets. 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 to F Beginning: " + trues); List<String> falses = f.get(Boolean.FALSE); System.out.println("with F Beginning: " + falses);
Generally, this method is not recommended for use in this scenario and does not comply with this requirement Api Design intent.
6. Summary
Today we studied some from Collections Methods and precautions for deleting elements in. I wonder if you have any other way to achieve it, so you can pass the official account number: Felordcn tell me.