add new method 'uniq()'

This commit is contained in:
2019-08-22 19:21:24 +02:00
parent ed703db277
commit 506fb7b698
4 changed files with 146 additions and 2 deletions

View File

@@ -54,7 +54,9 @@ public final class IntList implements Serializable, Cloneable {
/** /**
* Keeps track of whether or not the list is sorted. This allows us to use * Keeps track of whether or not the list is sorted. This allows us to use
* binary search for {@link #indexOf(int)}. An empty list is sorted. * binary search for {@link #indexOf(int)} and efficient algorithms for
* {@link #intersection(IntList, IntList)} / {@link #union(IntList, IntList)} /
* {@link #uniq()} / {@link #removeAll(int, int)}. An empty list is sorted.
*/ */
private boolean sorted = true; private boolean sorted = true;
@@ -680,6 +682,38 @@ public final class IntList implements Serializable, Cloneable {
checkIfSorted(); checkIfSorted();
} }
/**
* Removes all duplicate values from the list. The list will be sorted if it is
* not already sorted.
*
* The list can have unused capacity. Consider using {@link #trim()}.
*/
public void uniq() {
if (size <= 1) {
// nothing to do
return;
}
if (!sorted) {
sort();
}
uniqSorted();
}
private void uniqSorted() {
int insertPosition = 1;
int prev = data[0];
for (int i = 1; i < size; i++) {
final int current = data[i];
if (prev != current) {
data[insertPosition] = current;
insertPosition++;
prev = current;
}
}
size = insertPosition;
}
private void ensureCapacity(final int newElements) { private void ensureCapacity(final int newElements) {
final int requiredCapacity = size + newElements; final int requiredCapacity = size + newElements;

View File

@@ -39,7 +39,10 @@ public final class LongList implements Serializable, Cloneable {
/** /**
* Keeps track of whether or not the list is sorted. This allows us to use * Keeps track of whether or not the list is sorted. This allows us to use
* binary search for {@link #indexOf(int)}. An empty list is sorted. * binary search for {@link #indexOf(int)} and efficient algorithms for
* {@link #intersection(LongList, LongList)} /
* {@link #union(LongList, LongList)} / {@link #uniq()} /
* {@link #removeAll(int, int)}. An empty list is sorted.
*/ */
private boolean sorted = true; private boolean sorted = true;
@@ -685,6 +688,38 @@ public final class LongList implements Serializable, Cloneable {
checkIfSorted(); checkIfSorted();
} }
/**
* Removes all duplicate values from the list. The list will be sorted if it is
* not already sorted.
*
* The list can have unused capacity. Consider using {@link #trim()}.
*/
public void uniq() {
if (size <= 1) {
// nothing to do
return;
}
if (!sorted) {
sort();
}
uniqSorted();
}
private void uniqSorted() {
int insertPosition = 1;
long prev = data[0];
for (int i = 1; i < size; i++) {
final long current = data[i];
if (prev != current) {
data[insertPosition] = current;
insertPosition++;
prev = current;
}
}
size = insertPosition;
}
private void ensureCapacity(final int newElements) { private void ensureCapacity(final int newElements) {
final int requiredCapacity = size + newElements; final int requiredCapacity = size + newElements;
@@ -1182,4 +1217,5 @@ public final class LongList implements Serializable, Cloneable {
sorted = data[i - 1] <= data[i]; sorted = data[i - 1] <= data[i];
} }
} }
} }

View File

@@ -1635,4 +1635,41 @@ public class IntListTest {
Assertions.assertEquals(IntList.of(1, 2, 3, 4, 5), actual); Assertions.assertEquals(IntList.of(1, 2, 3, 4, 5), actual);
Assertions.assertEquals(IntList.union(a, b), IntList.union(b, a)); Assertions.assertEquals(IntList.union(a, b), IntList.union(b, a));
} }
@Test
public void testUniq_sorted() {
final IntList sorted = IntList.of(1, 1, 2, 3, 4, 4, 4);
final IntList expected = IntList.of(1, 2, 3, 4);
sorted.uniq();
Assertions.assertEquals(expected, sorted);
}
@Test
public void testUniq_empty() {
final IntList empty = IntList.of();
final IntList expected = IntList.of();
empty.uniq();
Assertions.assertEquals(expected, empty);
}
@Test
public void testUniq_oneElement() {
final IntList list = IntList.of(1);
final IntList expected = IntList.of(1);
list.uniq();
Assertions.assertEquals(expected, list);
}
@Test
public void testUniq_unsorted() {
final IntList unsorted = IntList.of(1, 1, 2, 3, 4, 4, 4);
unsorted.shuffle();
final IntList expected = IntList.of(1, 2, 3, 4);
unsorted.uniq();
Assertions.assertEquals(expected, unsorted);
}
} }

View File

@@ -1625,4 +1625,41 @@ public class LongListTest {
Assertions.assertEquals(LongList.of(1, 2, 3, 4, 5), actual); Assertions.assertEquals(LongList.of(1, 2, 3, 4, 5), actual);
Assertions.assertEquals(LongList.union(a, b), LongList.union(b, a)); Assertions.assertEquals(LongList.union(a, b), LongList.union(b, a));
} }
@Test
public void testUniq_sorted() {
final LongList sorted = LongList.of(1, 1, 2, 3, 4, 4, 4);
final LongList expected = LongList.of(1, 2, 3, 4);
sorted.uniq();
Assertions.assertEquals(expected, sorted);
}
@Test
public void testUniq_empty() {
final LongList empty = LongList.of();
final LongList expected = LongList.of();
empty.uniq();
Assertions.assertEquals(expected, empty);
}
@Test
public void testUniq_oneElement() {
final LongList list = LongList.of(1);
final LongList expected = LongList.of(1);
list.uniq();
Assertions.assertEquals(expected, list);
}
@Test
public void testUniq_unsorted() {
final LongList unsorted = LongList.of(1, 1, 2, 3, 4, 4, 4);
unsorted.shuffle();
final LongList expected = LongList.of(1, 2, 3, 4);
unsorted.uniq();
Assertions.assertEquals(expected, unsorted);
}
} }