Skip to content

Commit 288aeae

Browse files
lmcreanGoogle Java Core Libraries
authored andcommitted
Add a unit test for Iterators.mergeSorted().
RELNOTES=n/a PiperOrigin-RevId: 807210895
1 parent 087f2c4 commit 288aeae

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

android/guava-tests/test/com/google/common/collect/IteratorsTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@
6161
import java.util.Arrays;
6262
import java.util.Collection;
6363
import java.util.Collections;
64+
import java.util.Comparator;
6465
import java.util.ConcurrentModificationException;
6566
import java.util.Enumeration;
6667
import java.util.Iterator;
6768
import java.util.LinkedHashSet;
6869
import java.util.List;
6970
import java.util.ListIterator;
7071
import java.util.NoSuchElementException;
72+
import java.util.Objects;
7173
import java.util.RandomAccess;
7274
import java.util.Set;
7375
import java.util.Vector;
@@ -1546,4 +1548,74 @@ public void testPeekingIteratorShortCircuit() {
15461548
assertSame(peek, Iterators.peekingIterator(peek));
15471549
assertSame(peek, Iterators.peekingIterator((Iterator<String>) peek));
15481550
}
1551+
1552+
public void testMergeSorted_stable_issue5773Example() {
1553+
ImmutableList<TestDatum> left = ImmutableList.of(new TestDatum("B", 1), new TestDatum("C", 1));
1554+
ImmutableList<TestDatum> right = ImmutableList.of(new TestDatum("A", 2), new TestDatum("C", 2));
1555+
1556+
Comparator<TestDatum> comparator = Comparator.comparing(d -> d.letter);
1557+
1558+
// When elements compare as equal (both C's have same letter), our merge should always return C1
1559+
// before C2, since C1 is from the first iterator.
1560+
1561+
Iterator<TestDatum> merged =
1562+
Iterators.mergeSorted(ImmutableList.of(left.iterator(), right.iterator()), comparator);
1563+
1564+
ImmutableList<TestDatum> result = ImmutableList.copyOf(merged);
1565+
1566+
assertThat(result)
1567+
.containsExactly(
1568+
new TestDatum("A", 2),
1569+
new TestDatum("B", 1),
1570+
new TestDatum("C", 1),
1571+
new TestDatum("C", 2));
1572+
}
1573+
1574+
public void testMergeSorted_stable_allEqual() {
1575+
ImmutableList<TestDatum> first = ImmutableList.of(new TestDatum("A", 1), new TestDatum("A", 2));
1576+
ImmutableList<TestDatum> second =
1577+
ImmutableList.of(new TestDatum("A", 3), new TestDatum("A", 4));
1578+
1579+
Comparator<TestDatum> comparator = Comparator.comparing(d -> d.letter);
1580+
Iterator<TestDatum> merged =
1581+
Iterators.mergeSorted(ImmutableList.of(first.iterator(), second.iterator()), comparator);
1582+
1583+
ImmutableList<TestDatum> result = ImmutableList.copyOf(merged);
1584+
1585+
assertThat(result)
1586+
.containsExactly(
1587+
new TestDatum("A", 1),
1588+
new TestDatum("A", 2),
1589+
new TestDatum("A", 3),
1590+
new TestDatum("A", 4));
1591+
}
1592+
1593+
private static final class TestDatum {
1594+
final String letter;
1595+
final int number;
1596+
1597+
TestDatum(String letter, int number) {
1598+
this.letter = letter;
1599+
this.number = number;
1600+
}
1601+
1602+
@Override
1603+
public String toString() {
1604+
return letter + number;
1605+
}
1606+
1607+
@Override
1608+
public boolean equals(@Nullable Object o) {
1609+
if (!(o instanceof TestDatum)) {
1610+
return false;
1611+
}
1612+
TestDatum other = (TestDatum) o;
1613+
return letter.equals(other.letter) && number == other.number;
1614+
}
1615+
1616+
@Override
1617+
public int hashCode() {
1618+
return Objects.hash(letter, number);
1619+
}
1620+
}
15491621
}

guava-tests/test/com/google/common/collect/IteratorsTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@
6161
import java.util.Arrays;
6262
import java.util.Collection;
6363
import java.util.Collections;
64+
import java.util.Comparator;
6465
import java.util.ConcurrentModificationException;
6566
import java.util.Enumeration;
6667
import java.util.Iterator;
6768
import java.util.LinkedHashSet;
6869
import java.util.List;
6970
import java.util.ListIterator;
7071
import java.util.NoSuchElementException;
72+
import java.util.Objects;
7173
import java.util.RandomAccess;
7274
import java.util.Set;
7375
import java.util.Vector;
@@ -1546,4 +1548,74 @@ public void testPeekingIteratorShortCircuit() {
15461548
assertSame(peek, Iterators.peekingIterator(peek));
15471549
assertSame(peek, Iterators.peekingIterator((Iterator<String>) peek));
15481550
}
1551+
1552+
public void testMergeSorted_stable_issue5773Example() {
1553+
ImmutableList<TestDatum> left = ImmutableList.of(new TestDatum("B", 1), new TestDatum("C", 1));
1554+
ImmutableList<TestDatum> right = ImmutableList.of(new TestDatum("A", 2), new TestDatum("C", 2));
1555+
1556+
Comparator<TestDatum> comparator = Comparator.comparing(d -> d.letter);
1557+
1558+
// When elements compare as equal (both C's have same letter), our merge should always return C1
1559+
// before C2, since C1 is from the first iterator.
1560+
1561+
Iterator<TestDatum> merged =
1562+
Iterators.mergeSorted(ImmutableList.of(left.iterator(), right.iterator()), comparator);
1563+
1564+
ImmutableList<TestDatum> result = ImmutableList.copyOf(merged);
1565+
1566+
assertThat(result)
1567+
.containsExactly(
1568+
new TestDatum("A", 2),
1569+
new TestDatum("B", 1),
1570+
new TestDatum("C", 1),
1571+
new TestDatum("C", 2));
1572+
}
1573+
1574+
public void testMergeSorted_stable_allEqual() {
1575+
ImmutableList<TestDatum> first = ImmutableList.of(new TestDatum("A", 1), new TestDatum("A", 2));
1576+
ImmutableList<TestDatum> second =
1577+
ImmutableList.of(new TestDatum("A", 3), new TestDatum("A", 4));
1578+
1579+
Comparator<TestDatum> comparator = Comparator.comparing(d -> d.letter);
1580+
Iterator<TestDatum> merged =
1581+
Iterators.mergeSorted(ImmutableList.of(first.iterator(), second.iterator()), comparator);
1582+
1583+
ImmutableList<TestDatum> result = ImmutableList.copyOf(merged);
1584+
1585+
assertThat(result)
1586+
.containsExactly(
1587+
new TestDatum("A", 1),
1588+
new TestDatum("A", 2),
1589+
new TestDatum("A", 3),
1590+
new TestDatum("A", 4));
1591+
}
1592+
1593+
private static final class TestDatum {
1594+
final String letter;
1595+
final int number;
1596+
1597+
TestDatum(String letter, int number) {
1598+
this.letter = letter;
1599+
this.number = number;
1600+
}
1601+
1602+
@Override
1603+
public String toString() {
1604+
return letter + number;
1605+
}
1606+
1607+
@Override
1608+
public boolean equals(@Nullable Object o) {
1609+
if (!(o instanceof TestDatum)) {
1610+
return false;
1611+
}
1612+
TestDatum other = (TestDatum) o;
1613+
return letter.equals(other.letter) && number == other.number;
1614+
}
1615+
1616+
@Override
1617+
public int hashCode() {
1618+
return Objects.hash(letter, number);
1619+
}
1620+
}
15491621
}

0 commit comments

Comments
 (0)