Add CollectionUtils.duplicate[List|Set]
- Add CollectionUtils.duplicateList(Collection<E>) - Add CollectionUtils.duplicateSequencedSet(Collection<E>) - Add CollectionUtils.duplicateSet(Collection<E>)
This commit is contained in:
parent
fa76c00a4f
commit
77faa5be8f
|
@ -37,6 +37,9 @@
|
||||||
<action type="fix" dev="ggregory" due-to="Dávid Szigecsán">Use the Junit (Jupiter) API #518.</action>
|
<action type="fix" dev="ggregory" due-to="Dávid Szigecsán">Use the Junit (Jupiter) API #518.</action>
|
||||||
<!-- ADD -->
|
<!-- ADD -->
|
||||||
<action type="add" dev="ggregory" due-to="Dávid Szigecsán">LayerManager.Builder implements Supplier.</action>
|
<action type="add" dev="ggregory" due-to="Dávid Szigecsán">LayerManager.Builder implements Supplier.</action>
|
||||||
|
<action type="add" dev="ggregory" due-to="Gary Gregory, hemanth0525">Add CollectionUtils.duplicateList(Collection).</action>
|
||||||
|
<action type="add" dev="ggregory" due-to="Gary Gregory, hemanth0525">Add CollectionUtils.duplicateSet(Collection).</action>
|
||||||
|
<action type="add" dev="ggregory" due-to="Gary Gregory, hemanth0525">Add CollectionUtils.duplicateSequencedSet(Collection).</action>
|
||||||
<!-- UPDATE -->
|
<!-- UPDATE -->
|
||||||
<action issue="COLLECTIONS-857" type="update" dev="ggregory" due-to="Claude Warren">Update bloom filter documentation #508.</action>
|
<action issue="COLLECTIONS-857" type="update" dev="ggregory" due-to="Claude Warren">Update bloom filter documentation #508.</action>
|
||||||
<action issue="COLLECTIONS-857" type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514.</action>
|
<action issue="COLLECTIONS-857" type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514.</action>
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -756,6 +757,62 @@ public class CollectionUtils {
|
||||||
return helper.list();
|
return helper.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and returns the List of duplicate elements in the given collection.
|
||||||
|
*
|
||||||
|
* @param <E> the type of elements in the collection.
|
||||||
|
* @param collection the list to test, must not be null.
|
||||||
|
* @return the set of duplicate elements, may be empty.
|
||||||
|
* @since 4.5.0-M3
|
||||||
|
*/
|
||||||
|
public static <E> List<E> duplicateList(final Collection<E> collection) {
|
||||||
|
return new ArrayList<>(duplicateSet(collection));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and returns the sequenced Set of duplicate elements in the given collection.
|
||||||
|
* <p>
|
||||||
|
* Once we are on Java 21 and a new major version, the return type should be SequencedSet.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param <E> the type of elements in the collection.
|
||||||
|
* @param collection the list to test, must not be null.
|
||||||
|
* @return the set of duplicate elements, may be empty.
|
||||||
|
* @since 4.5.0-M3
|
||||||
|
*/
|
||||||
|
public static <E> Set<E> duplicateSequencedSet(final Collection<E> collection) {
|
||||||
|
return duplicateSet(collection, new LinkedHashSet<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and returns the set of duplicate elements in the given collection.
|
||||||
|
*
|
||||||
|
* @param <E> the type of elements in the collection.
|
||||||
|
* @param collection the list to test, must not be null.
|
||||||
|
* @return the set of duplicate elements, may be empty.
|
||||||
|
* @since 4.5.0-M3
|
||||||
|
*/
|
||||||
|
public static <E> Set<E> duplicateSet(final Collection<E> collection) {
|
||||||
|
return duplicateSet(collection, new HashSet<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Worker method for {@link #duplicateSet(Collection)} and friends.
|
||||||
|
*
|
||||||
|
* @param <C> the type of Collection.
|
||||||
|
* @param <E> the type of elements in the Collection.
|
||||||
|
* @param collection the list to test, must not be null.
|
||||||
|
* @param duplicates the list to test, must not be null.
|
||||||
|
* @return the set of duplicate elements, may be empty.
|
||||||
|
*/
|
||||||
|
static <C extends Collection<E>, E> C duplicateSet(final Collection<E> collection, final C duplicates) {
|
||||||
|
final Set<E> set = new HashSet<>();
|
||||||
|
for (final E e : collection) {
|
||||||
|
(set.contains(e) ? duplicates : set).add(e);
|
||||||
|
}
|
||||||
|
return duplicates;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the immutable EMPTY_COLLECTION with generic type safety.
|
* Returns the immutable EMPTY_COLLECTION with generic type safety.
|
||||||
*
|
*
|
||||||
|
|
|
@ -26,17 +26,20 @@ import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -872,6 +875,137 @@ public class CollectionUtilsTest extends MockTestCase {
|
||||||
assertThrows(NullPointerException.class, () -> CollectionUtils.disjunction(list, null));
|
assertThrows(NullPointerException.class, () -> CollectionUtils.disjunction(list, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListAllSameInList() {
|
||||||
|
final List<Integer> input = Arrays.asList(5, 5, 5, 5);
|
||||||
|
assertEquals(Arrays.asList(5), CollectionUtils.duplicateList(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListEmptyDeque() {
|
||||||
|
assertTrue(CollectionUtils.duplicateList(new ArrayDeque<>()).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListEmptyList() {
|
||||||
|
final List<Integer> input = Arrays.asList();
|
||||||
|
assertTrue(CollectionUtils.duplicateList(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListEmptySet() {
|
||||||
|
assertTrue(CollectionUtils.duplicateList(new HashSet<>()).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListMultipleDuplicatesInDeque() {
|
||||||
|
final Deque<Integer> input = new ArrayDeque<>(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4));
|
||||||
|
final List<Integer> expected = Arrays.asList(1, 2, 3, 4);
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateList(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListMultipleDuplicatesInList() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4);
|
||||||
|
final List<Integer> expected = Arrays.asList(1, 2, 3, 4);
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateList(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListNoDuplicates() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
assertTrue(CollectionUtils.duplicateList(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListSingleElement() {
|
||||||
|
final List<Integer> input = Arrays.asList(1);
|
||||||
|
assertTrue(CollectionUtils.duplicateList(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateListWithDuplicates() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 2, 3, 2, 4, 5, 3);
|
||||||
|
final List<Integer> expected = Arrays.asList(2, 3);
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateList(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSequencedSetMultipleDuplicates() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4);
|
||||||
|
final List<Integer> list = Arrays.asList(1, 2, 3, 4);
|
||||||
|
assertEquals(list, new ArrayList<>(CollectionUtils.duplicateSequencedSet(input)));
|
||||||
|
assertEquals(new LinkedHashSet<>(list), CollectionUtils.duplicateSequencedSet(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetEmptyDeque() {
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(new ArrayDeque<>()).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetEmptyList() {
|
||||||
|
final List<Integer> input = Arrays.asList();
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetEmptySet() {
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(new HashSet<>()).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetInSet() {
|
||||||
|
// Sets don't have duplicates, so the result is always an empty set.
|
||||||
|
final Set<Integer> input = new HashSet<>(Arrays.asList(5));
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetMultipleDuplicatesInDeque() {
|
||||||
|
final Deque<Integer> input = new ArrayDeque<>(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4));
|
||||||
|
final Set<Integer> expected = new HashSet<>(Arrays.asList(1, 2, 3, 4));
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateSet(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetMultipleDuplicatesInList() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4);
|
||||||
|
final Set<Integer> expected = new HashSet<>(Arrays.asList(1, 2, 3, 4));
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateSet(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetNoDuplicates() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetSingleElement() {
|
||||||
|
final List<Integer> input = Arrays.asList(1);
|
||||||
|
assertTrue(CollectionUtils.duplicateSet(input).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateSetWithDuplicates() {
|
||||||
|
final List<Integer> input = Arrays.asList(1, 2, 3, 2, 4, 5, 3);
|
||||||
|
final Set<Integer> expected = new HashSet<>(Arrays.asList(2, 3));
|
||||||
|
assertEquals(expected, CollectionUtils.duplicateSet(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicatListAllSameInDeque() {
|
||||||
|
final Deque<Integer> input = new ArrayDeque<>(Arrays.asList(5, 5, 5, 5));
|
||||||
|
assertEquals(Arrays.asList(5), CollectionUtils.duplicateList(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicatSetAllSameInDeque() {
|
||||||
|
final Deque<Integer> input = new ArrayDeque<>(Arrays.asList(5, 5, 5, 5));
|
||||||
|
assertEquals(new HashSet<>(Arrays.asList(5)), CollectionUtils.duplicateSet(input));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyCollection() throws Exception {
|
public void testEmptyCollection() throws Exception {
|
||||||
final Collection<Number> coll = CollectionUtils.emptyCollection();
|
final Collection<Number> coll = CollectionUtils.emptyCollection();
|
||||||
|
|
Loading…
Reference in New Issue