TreeMultiSet
TreeSet that supports repeatable elements based on TreeMap implementation
Anyone who has worked with Java knows TreeSet, but TreeSet does not support repeating elements. One might say, why not ArrayList or LinkedList? Indeed, arrayLists or LinkedLists are naturally unweighted and can meet the need to support repeating elements. However, NOT only do I need to support repeatable elements, but I also need the data to stay in order in real time.
Somebody here says again, isn’t order easy? After I insert the data into the ArrayList or LinkedList, I call sort and I’m done. Well, sure, if your List doesn’t change very often (sort is very, very rare), then you can certainly use List+sort. But what if the data is constantly changing? 【 References 】
If the data is constantly changing and you need to keep the data in order in real time (e.g., there are minimum and maximum requirements for real-time queries), the time complexity is very high if you use List+sort: So the single insertion time is O(n)O(n), and if you have n elements, you need O(n^2)O(n 2). So, if we want to reduce time complexity, we can’t use lists.
Then someone said, I just use TreeMap seems to be ok. The key of a TreeMap is an element, and the value is the number of occurrences of the element corresponding to the key. This satisfies the need for repeatable and ordered inserts. [Ref.] Indeed, this can meet the requirement of repeatable and ordered roughly. However, here are a few disadvantages of using TreeMap for repeatable and ordered requirements:
If we need to know the number of sets of repeatable elements (the number of repeating elements counts as multiple), we can’t get it immediately and within O(1)O(1) time using TreeMap. Instead, we need to loop through all keys and then compute the sum of all values. The general code is as follows:
int size = 0;
for (Integer num : treeMap.keySet()) {
size += treeMap.get(num);
}
Copy the code
Does that seem like a bit of a hassle? To get the number of sets, we should expect the following to be succinct:
set.size();
Copy the code
If we need to iterate over all the elements in the collection, repeating elements need to be iterate over multiple times (similar to the list). Using TreeMap to do this requires a double loop, which is not intuitive. As follows:
for (Integer num : treeMap.keySet()) {
int count = treeMap.get(num);
while ((count--) > 0) {
// Use a loop to print num count timesSystem.out.println(num); }}Copy the code
Again, we should expect a repeat loop, like the following:
for (Integer num : set) {
System.out.println(num);
}
Copy the code
If we need to delete a specified number of elements in the set. For example, set [1, 2, 2, 3, 3, 3]. I just want to delete two 3’s, TreeMap needs to do this:
if (treeMap.containsKey(3)) {
treeMap.put(2, treeMap.get(3) - 2);
}
Copy the code
Again, we should expect something like this:
set.remove(3.2); // The second argument represents the number of elements to delete
// If we need to add a specified number of elements to the collection. For example, set [1, 2, 2, 2, 4], we need to add two 4's, TreeMap needs to do this:
// Join Java development chat
treeMap.put(4, treeMap.getOrDefault(4.0) + 2);
// Again, we should expect something like this:
set.add(4.2); // The second argument represents the number of elements to be inserted
Copy the code
In addition, there are a few less elegant ways in which TreeMap implements the functionality of a repeatable TreeSet, which I won’t list here.
Hence, TreeMultiSet was born. (Just for the record: TreeMultiSet is mostly realized by referring to TreeSet, which is actually based on TreeMap, and the bottom layer of TreeMap is realized by red-black Tree. This is also the essential reason why TreeSet’s remove operation can achieve O(logN) time complexity.
How to use
gradle
Step 1. Add the JitPack repository in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io'}}}// Join Java development chat
Step 2. Add the dependency in your app build.gradle:
dependencies {
implementation 'com. Making. Yuruiyin: TreeMultiSet: 1.0.1'
}
Copy the code
Feature list
No parameter constructor | TreeMultiSet() |
---|---|
Constructor with comparator arguments | TreeMultiSet(Comparator<? super E> comparator) |
Constructor with set arguments | TreeMultiSet(Collection<? extends E> c) |
Constructor with SortedSet parameter | TreeMultiSet(SortedSet<E> s) |
Returns a forward iterator for all elements that are repeated several times next | Iterator<E> iterator() |
Returns a reverse iterator for all elements that are repeated multiple times | Iterator<E> descendingIterator() |
Returns a forward iterator for all distinct elements | Iterator<E> diffIterator() |
Returns a reverse iterator for all distinct elements | Iterator<E> diffDescendingIterator() |
Return reverse Set | NavigableSet<E> descendingSet() |
Returns a continuous subset of the specified header and tail elements | NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) |
Returns a continuous subset of headers | NavigableSet<E> headSet(E toElement, boolean inclusive) |
Returns a tail continuous subset | NavigableSet<E> tailSet(E fromElement, boolean inclusive) |
Return comparator | Comparator<? super E> comparator() |
Return the total number of elements. | int size() |
Returns a different number of elements | int diffElementSize() |
Gets the first element | E first() |
Gets the last element | E last() |
Determines whether an element is included | boolean contains(Object o) |
Clear all elements | void clear() |
Add the specified element (1) | boolean add(E e) |
Adds a specified number of specific elements | boolean add(E e, int count) |
Sets the number of specified elements | void setCount(E e, int count) |
Gets the number of specified elements | int count(E e) |
Deletes 1 specified element | boolean remove(Object e) |
Deletes count specified elements | boolean remove(E e, int count) |
Remove all specified elements (unlike clear()) | boolean removeAll(Object e) |
Returns the largest element that is strictly smaller than the given element | E lower(E e) |
Returns the largest element less than or equal to the given element | E floor(E e) |
Returns the smallest element that is strictly greater than the given element | E higher(E e) |
Returns the smallest element greater than or equal to the given element | E ceiling(E e) |
Deletes the first element of the specified count | E pollFirst(int count) |
Delete 1 first element | E pollFirst() |
Delete the first element of all counts | E pollFirstAll() |
Delete 1 last element | E pollLast() |
Deletes the last element of the specified count | E pollLast(int count) |
Removes the last element of all counts | E pollLastAll() |
TreeMultiSet shallow copy | Object clone() |
Code demo
Here are a few ways to call some methods that I think are commonly used
1) Create a new TreeMultiSet for a custom comparator
TreeMultiSet<Integer> set = new TreeMultiSet<>((o1, o2) -> o2 - o1); // Pass a big-to-small comparator
Copy the code
2) Foreach traverses all elements (including repeating elements)
for (Integer num : set) {
// TODO, which can output sequences like 2, 2, 2, 3
}
Copy the code
3) Get forward iterators for all elements (including repeating elements)
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
arr[i++] = iterator.next();
}
Copy the code
4) Get forward iterators for different elements
Iterator<Integer> diffIterator = set.diffIterator();
while (diffIterator.hasNext()) {
arr[i++] = diffIterator.next();
}
Copy the code
5) Get the total number of elements (including duplicate elements)
set.size();
Copy the code
6) Get the number of different elements
set.diffElementSize();
Copy the code
7) Get the first and last element
set.first();
set.last();
Copy the code
Add a specified number of elements
set.add(2.3); // Add 3 2's to the set
Copy the code
9) Set the number of specified elements
set.setCount(2.3); // Set the number of 2's in the set to 3
Copy the code
10) Get the number of specified elements
set.count(2); // Get the number of 2 in the set
Copy the code
11) Delete the specified number of elements
set.remove(2.3); // Delete 3 2's
Copy the code
12) Delete the specified number of first elements
set.pollFirst(2); // Delete 2 first elements. If the collection [1,1,1,2,2,3] executes this line of code and becomes [1,2,2,3]
Copy the code
13) Delete the last element of the specified number
set.pollLast(1); // Delete 1 last element. If the collection [1,1,1,2,3,3] executes this line of code and becomes [1,1,1,2,2,3]
Copy the code
Unit testing
TreeMultiSetTest has been unit tested on all methods of TreeMultiSet, including constructors, with 100% test coverage.
Various set contrast
Note the complexity listed below refers to the time complexity. And the following insert and delete operations refer to operations on intermediate elements. At the same time, the insertion and deletion time complexity of the LinkedList takes into account the query time to the location to be inserted or deleted.
Mysql, Netty, Spring, thread, Spring Cloud, JVM, source code, algorithm, etc., also have a detailed learning plan map, interview questions, etc., need to obtain these contents of the friend please add Q: sample: 756584822