Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7164256

EnumMap clone doesn't clear the entrySet keeping a reference to the original Map

XMLWordPrintable

    • 7
    • b43
    • x86
    • linux, windows_7
    • Verified

        FULL PRODUCT VERSION :
        java version "1.7.0_03"
        Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
        Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux medea 2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:39:49 UTC 2012 x86_64 GNU/Linux


        A DESCRIPTION OF THE PROBLEM :
        The EnumMap clone implementation does not clear the field entrySet. Therefore, any call to the method entrySet in a cloned map (with its entrySet initialized) ) will return a reference to the original entrySet instead of returning a new entrySet pointing to the new map instance.

        This breaks the Map.entrySet contract which states " Returns a Set view of the mappings contained in this map"

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        This happens every time a EnumMap, which has its entrySet initialized, is cloned. All changes made to the new instance won't be reflected by the EntrySet returned by the entrySet() method.

        Example:

        import java.util.EnumMap;
        import java.util.Map.Entry;


        public class TestEnumMap {
            public enum Test {
                ONE, TWO
            }

            public static void main(String[] args) {
                EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
                map1.put(Test.ONE, "1");
                map1.put(Test.TWO, "2");

                for (Entry<Test, String> entry : map1.entrySet()) {
                    System.out.println(entry);
                }

                System.out.println("---------------");

                EnumMap<Test, String> map2 = map1.clone();
                map2.remove(Test.ONE);
                for (Entry<Test, String> entry : map2.entrySet()) {
                    System.out.println(entry);
                }
            }
        }

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        ONE=1
        TWO=2
        ---------------
        TWO=2

        ACTUAL -
        ONE=1
        TWO=2
        ---------------
        ONE=1
        TWO=2


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.util.EnumMap;
        import java.util.Map.Entry;


        public class TestEnumMap {
            public enum Test {
                ONE, TWO
            }

            public static void main(String[] args) {
                EnumMap<Test, String> map1 = new EnumMap<Test, String>(Test.class);
                map1.put(Test.ONE, "1");
                map1.put(Test.TWO, "2");

                for (Entry<Test, String> entry : map1.entrySet()) {
                    System.out.println(entry);
                }

                System.out.println("---------------");

                EnumMap<Test, String> map2 = map1.clone();
                map2.remove(Test.ONE);
                for (Entry<Test, String> entry : map2.entrySet()) {
                    System.out.println(entry);
                }
            }
        }
        ---------- END SOURCE ----------

              alanb Alan Bateman
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: