Backport COLLECTIONS-307 to 3.2.2. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/branches/COLLECTIONS_3_2_X@1713295 13f79535-47bb-0310-9956-ffa450edef68
Project: http://git-wip-us.apache.org/repos/asf/commons-collections/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-collections/commit/81af3aaa Tree: http://git-wip-us.apache.org/repos/asf/commons-collections/tree/81af3aaa Diff: http://git-wip-us.apache.org/repos/asf/commons-collections/diff/81af3aaa Branch: refs/heads/COLLECTIONS_3_2_X Commit: 81af3aaa9a03e503e29799b9c3de9f3ddb3e875b Parents: d75768a Author: Thomas Neidhart <t...@apache.org> Authored: Sun Nov 8 21:12:28 2015 +0000 Committer: Thomas Neidhart <t...@apache.org> Committed: Sun Nov 8 21:12:28 2015 +0000 ---------------------------------------------------------------------- src/changes/changes.xml | 8 ++--- .../commons/collections/list/SetUniqueList.java | 30 +++++++++++++++- .../collections/list/TestSetUniqueList.java | 38 ++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-collections/blob/81af3aaa/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 053ccc5..a415a91 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -38,6 +38,10 @@ <action issue="COLLECTIONS-334" dev="jochen" type="fix" due-to="sebb"> Synchronized access to lock in "StaticBucketMap#size()". </action> + <action issue="COLLECTIONS-307" dev="bayard" type="fix" due-to="Christian Semrau"> + "SetUniqueList#subList()#contains(Object)" will now correctly check the subList + rather than the parent list. + </action> <action issue="COLLECTIONS-294" dev="bayard" type="fix" due-to="Benjamin Bentmann"> "CaseInsensitiveMap" will now convert input strings to lower-case in a locale-independent manner. @@ -82,10 +86,6 @@ <action issue="COLLECTIONS-330" dev="mbenson" type="fix" due-to="Joerg Schaible"> "LRUMap#keySet()#remove(Object)" will not throw a "ConcurrentModificationException" anymore. </action> - <action issue="COLLECTIONS-307" dev="bayard" type="fix" due-to="Christian Semrau"> - "SetUniqueList#subList()#contains(Object)" will now correctly check the subList - rather than the parent list. - </action> <action issue="COLLECTIONS-304" dev="bayard" type="fix" due-to="RafaÅ Figas,Bjorn Townsend"> "SetUniqueList#set(int, Object)" will now correctly enforce the uniqueness constraint. </action> http://git-wip-us.apache.org/repos/asf/commons-collections/blob/81af3aaa/src/java/org/apache/commons/collections/list/SetUniqueList.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/commons/collections/list/SetUniqueList.java b/src/java/org/apache/commons/collections/list/SetUniqueList.java index 3eb5f34..c9f0148 100644 --- a/src/java/org/apache/commons/collections/list/SetUniqueList.java +++ b/src/java/org/apache/commons/collections/list/SetUniqueList.java @@ -277,7 +277,35 @@ public class SetUniqueList extends AbstractSerializableListDecorator { } public List subList(int fromIndex, int toIndex) { - return new SetUniqueList(super.subList(fromIndex, toIndex), set); + List superSubList = super.subList(fromIndex, toIndex); + Set subSet = createSetBasedOnList(set, superSubList); + return new SetUniqueList(superSubList, subSet); + } + + /** + * Create a new {@link Set} with the same type as the provided {@code set} + * and populate it with all elements of {@code list}. + * + * @param set the {@link Set} to be used as return type, must not be null + * @param list the {@link List} to populate the {@link Set} + * @return a new {@link Set} populated with all elements of the provided + * {@link List} + */ + protected Set createSetBasedOnList(Set set, List list) { + Set subSet = null; + if(set.getClass().equals(HashSet.class)) { + subSet = new HashSet(); + } else { + try { + subSet = (Set) set.getClass().newInstance(); + } catch(InstantiationException ie) { + subSet = new HashSet(); + } catch(IllegalAccessException iae) { + subSet = new HashSet(); + } + } + subSet.addAll(list); + return subSet; } //----------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-collections/blob/81af3aaa/src/test/org/apache/commons/collections/list/TestSetUniqueList.java ---------------------------------------------------------------------- diff --git a/src/test/org/apache/commons/collections/list/TestSetUniqueList.java b/src/test/org/apache/commons/collections/list/TestSetUniqueList.java index fe08150..519cd59 100644 --- a/src/test/org/apache/commons/collections/list/TestSetUniqueList.java +++ b/src/test/org/apache/commons/collections/list/TestSetUniqueList.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; +import java.util.Set; import junit.framework.Test; import junit.framework.TestSuite; @@ -430,6 +431,43 @@ public class TestSetUniqueList extends AbstractTestList { assertTrue(s.contains(c)); } + public void testCollections307() { + List list = new ArrayList(); + List uniqueList = SetUniqueList.decorate(list); + String hello = "Hello"; + String world = "World"; + uniqueList.add(hello); + uniqueList.add(world); + List subList = list.subList(0, 0); + List subUniqueList = uniqueList.subList(0, 0); + assertFalse(subList.contains(world)); // passes + assertFalse(subUniqueList.contains(world)); // fails + List worldList = new ArrayList(); + worldList.add(world); + assertFalse(subList.contains("World")); // passes + assertFalse(subUniqueList.contains("World")); // fails + // repeat the test with a different class than HashSet; + // which means subclassing SetUniqueList below + list = new ArrayList(); + uniqueList = new SetUniqueList307(list, new java.util.TreeSet()); + uniqueList.add(hello); + uniqueList.add(world); + subList = list.subList(0, 0); + subUniqueList = uniqueList.subList(0, 0); + assertFalse(subList.contains(world)); // passes + assertFalse(subUniqueList.contains(world)); // fails + worldList = new ArrayList(); + worldList.add(world); + assertFalse(subList.contains("World")); // passes + assertFalse(subUniqueList.contains("World")); // fails + } + + class SetUniqueList307 extends SetUniqueList { + public SetUniqueList307(List list, Set set) { + super(list, set); + } + } + //----------------------------------------------------------------------- public String getCompatibilityVersion() { return "3.1";