Skip to content

TreeSet/TreeMap should implement Cloneable and offer clone() #10146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion user/super/com/google/gwt/emul/java/util/TreeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* @param <K> key type
* @param <V> value type
*/
public class TreeMap<K, V> extends AbstractNavigableMap<K, V> implements Serializable {
public class TreeMap<K, V> extends AbstractNavigableMap<K, V> implements Serializable, Cloneable {
/*
* Implementation derived from public domain C implementation as of 5
* September 2007 at:
Expand Down Expand Up @@ -502,6 +502,10 @@ public void clear() {
size = 0;
}

public Object clone() {
return new TreeMap<K, V>(this);
}

@Override
public Comparator<? super K> comparator() {
return Comparators.naturalOrderToNull(cmp);
Expand Down
7 changes: 6 additions & 1 deletion user/super/com/google/gwt/emul/java/util/TreeSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
*
* @param <E> element type.
*/
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Serializable {
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Serializable,
Cloneable {

/**
* TreeSet is stored as a TreeMap of the requested type to a constant Boolean.
Expand Down Expand Up @@ -77,6 +78,10 @@ public void clear() {
map.clear();
}

public Object clone() {
return new TreeSet(new TreeMap<E, Boolean>(map));
}

@Override
public Comparator<? super E> comparator() {
return map.comparator();
Expand Down
35 changes: 21 additions & 14 deletions user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -281,21 +281,28 @@ public void testClear_throwsUnsupportedOperationException() {

/** Test method for 'java.lang.Object.clone()'. */
public void testClone() {
// Map<K, V> map = createMap();
TreeMap<K, V> map = createTreeMap();
// Check empty clone behavior
// TODO (rlo) having .clone() in the code kills the test
// SortedMap<K, V> clone = (SortedMap<K, V>)
// map.clone();
// assertNotNull(clone);
// testEquivalent(map, clone);
//
// // Check non-empty clone behavior
// map.put(KEY_1, getValues()[0]);
// map.put(KEY_2, getValues()[1]);
// map.put(KEY_3, getValues()[2]);
// clone = (SortedMap<K, V>) map.clone();
// assertNotNull(clone);
// testEquivalent(map, clone);
SortedMap<K, V> clone = (SortedMap<K, V>) map.clone();
assertNotNull(clone);
_assertEquals(map, clone);
assertSame(map.comparator(), clone.comparator());

// Check non-empty clone behavior
K[] keys = getKeys();
V[] values = getValues();
map.put(keys[0], values[0]);
map.put(keys[1], values[1]);
map.put(keys[2], values[2]);

// Ensure no shared state between original and clone
assertFalse(map.equals(clone));

// Clone the non-empty map
clone = (SortedMap<K, V>) map.clone();
assertNotNull(clone);
_assertEquals(map, clone);
assertSame(map.comparator(), clone.comparator());
}

/**
Expand Down
12 changes: 12 additions & 0 deletions user/test/com/google/gwt/emultest/java/util/TreeSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,18 @@ public void testEquals() {
assertFalse(set0.equals(set1));
}

public void testSetClone() {
TreeSet<E> set = createTreeSet();
TreeSet<E> clone = (TreeSet<E>) set.clone();
assertEquals(set, clone);

set.add(getKeys()[0]);
assertFalse(set.equals(clone));

clone = (TreeSet<E>) set.clone();
assertEquals(set, clone);
}

/**
* Test method for 'java.util.SortedSet.first()'.
*
Expand Down