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";

Reply via email to