View Javadoc
1   package org.djutils.immutablecollections;
2   
3   import java.util.Iterator;
4   import java.util.Map;
5   import java.util.Map.Entry;
6   import java.util.NavigableMap;
7   import java.util.Set;
8   import java.util.TreeMap;
9   
10  import org.djutils.immutablecollections.ImmutableMap.ImmutableEntry;
11  import org.junit.Assert;
12  import org.junit.Test;
13  
14  /**
15   * TestImmutableTreeMap.java.
16   * <p>
17   * Copyright (c) 2002-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
18   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
19   * distributed under a three-clause BSD-style license, which can be found at
20   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
21   * </p>
22   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank"> Alexander Verbraeck</a>
23   */
24  public class TestImmutableTreeMap
25  {
26  
27      /**
28       * ...
29       */
30      @SuppressWarnings({"unlikely-arg-type"})
31      @Test
32      public final void testTreeMap()
33      {
34          NavigableMap<Integer, Integer> isMap = new TreeMap<>();
35          for (int i = 1; i <= 10; i++)
36          {
37              isMap.put(i, 100 * i);
38          }
39          NavigableMap<Integer, Integer> map = new TreeMap<Integer, Integer>(isMap);
40          testIntMap(map, new ImmutableTreeMap<Integer, Integer>(map, Immutable.WRAP), Immutable.WRAP);
41          map = new TreeMap<Integer, Integer>(isMap);
42          testIntMap(map, new ImmutableTreeMap<Integer, Integer>(map, Immutable.COPY), Immutable.COPY);
43          map = new TreeMap<Integer, Integer>(isMap);
44          testIntMap(map, new ImmutableTreeMap<Integer, Integer>(map), Immutable.COPY);
45          map = new TreeMap<Integer, Integer>(isMap);
46          ImmutableTreeMap<Integer, Integer> ihs = new ImmutableTreeMap<Integer, Integer>(map);
47          testIntMap(map, new ImmutableTreeMap<Integer, Integer>(ihs), Immutable.COPY);
48  
49          ImmutableTreeMap<Integer, Integer> itm = new ImmutableTreeMap<>(isMap, Immutable.WRAP);
50          ImmutableTreeMap<Integer, Integer> itmw = new ImmutableTreeMap<>(itm, Immutable.WRAP);
51          Assert.assertEquals("wrapper is equal to wrapped", itm, itmw);
52          itmw = new ImmutableTreeMap<>(itm, Immutable.COPY);
53          Assert.assertEquals("copied is equal to wrapped", itm, itmw);
54          Assert.assertEquals("wrapped is equal to copied", itmw, itm);
55          Assert.assertTrue("toString returns something descriptive", itm.toString().startsWith("ImmutableTreeMap ["));
56          ImmutableTreeMap<Integer, Integer> subMap = (ImmutableTreeMap<Integer, Integer>) itm.subMap(3, 5);
57          Assert.assertEquals("size is 2", 2, subMap.size());
58          Assert.assertEquals("first key is 3", 3, subMap.firstKey(), 0);
59          Assert.assertEquals("last key is 4", 4, subMap.lastKey(), 0);
60          Assert.assertNull("sub map has no value for key 2", subMap.get(2));
61          Assert.assertNull("sub map has no value for key 5", subMap.get(5));
62          Assert.assertEquals("value for key 3 is 300", 300, subMap.get(3), 0);
63          Assert.assertEquals("value for key 4 is 400", 400, subMap.get(4), 0);
64          subMap = (ImmutableTreeMap<Integer, Integer>) itm.subMap(2, true, 6, true);
65          Assert.assertEquals("first key is 2", 2, subMap.firstKey(), 0);
66          Assert.assertEquals("last key is 6", 6, subMap.lastKey(), 0);
67          ImmutableTreeMap<Integer, Integer> headMap = (ImmutableTreeMap<Integer, Integer>) itm.headMap(5);
68          Assert.assertEquals("headMap has 4 entries", 4, headMap.size());
69          Assert.assertEquals("first key is 1", 1, headMap.firstKey(), 0);
70          Assert.assertEquals("last key is 4", 4, headMap.lastKey(), 0);
71          headMap = (ImmutableTreeMap<Integer, Integer>) itm.headMap(5, true);
72          Assert.assertEquals("headMap has 5 entries", 5, headMap.size());
73          Assert.assertEquals("first key is 1", 1, headMap.firstKey(), 0);
74          Assert.assertEquals("last key is 5", 5, headMap.lastKey(), 0);
75          ImmutableTreeMap<Integer, Integer> tailMap = (ImmutableTreeMap<Integer, Integer>) itm.tailMap(5);
76          Assert.assertEquals("tailMap has 6 entries", 6, tailMap.size());
77          Assert.assertEquals("first key is 5", 5, tailMap.firstKey(), 0);
78          tailMap = (ImmutableTreeMap<Integer, Integer>) itm.tailMap(5, false);
79          Assert.assertEquals("tailMap has 5 entries", 5, tailMap.size());
80          Assert.assertEquals("first key is 6", 6, tailMap.firstKey(), 0);
81          Assert.assertNull("there is no lower key than 1", itm.lowerKey(1));
82          Assert.assertEquals("highest key lower than 5 is 4", 4, itm.lowerKey(5), 0);
83          Assert.assertEquals("highest key lower than 999 is 10", 10, itm.lowerKey(999), 0);
84          Assert.assertEquals("highest key lower than, or equal to 5 is s", 5, itm.floorKey(5), 0);
85          Assert.assertNull("highest key lower than, or equal to 0 does not exist", itm.floorKey(0));
86          Assert.assertEquals("lowest key equal or bigger than 3 is 3", 3, itm.ceilingKey(3), 0);
87          Assert.assertNull("lowest key equal or bigger than 11 does not exist", itm.ceilingKey(11));
88          Assert.assertEquals("lowest key bigger than -10 is 1", 1, itm.higherKey(-10), 0);
89          Assert.assertEquals("lowest key bigger than 5 is 6", 6, itm.higherKey(5), 0);
90          Assert.assertNull("lowest key bigger than 10 does not exist", itm.higherKey(10));
91          ImmutableTreeMap<Integer, Integer> descending = (ImmutableTreeMap<Integer, Integer>) itm.descendingMap();
92          Assert.assertEquals("descending map has same size", itm.size(), descending.size());
93          ImmutableSet<ImmutableEntry<Integer, Integer>> entrySet = itm.entrySet();
94          Iterator<ImmutableEntry<Integer, Integer>> iterator = entrySet.iterator();
95          ImmutableEntry<Integer, Integer> sampleEntry = iterator.next();
96          Assert.assertEquals("ImmutableEntry is equal to itself", sampleEntry, sampleEntry);
97          Assert.assertFalse("entry is not equal to null", sampleEntry.equals(null));
98          Assert.assertFalse("entry is not equal to some other object", sampleEntry.equals("ABC"));
99          ImmutableEntry<Integer, Integer> differentEntry = iterator.next();
100         Assert.assertFalse("entry is not equal to the next entry", sampleEntry.equals(differentEntry));
101         ImmutableEntry<Integer, Integer> copy = new ImmutableEntry<Integer, Integer>(isMap.firstEntry());
102         Assert.assertEquals("wrapped entry is equal to self made entry containing same entry", sampleEntry, copy);
103         ImmutableEntry<Integer, Integer> containsNull = new ImmutableEntry<Integer, Integer>(null);
104         Assert.assertFalse("wrapped entry is not equal to self made entry contaning null", sampleEntry.equals(containsNull));
105         Assert.assertFalse("Self made entry containing null is not equal to sampleEntry", containsNull.equals(sampleEntry));
106         ImmutableEntry<Integer, Integer> otherContainsNull = new ImmutableEntry<Integer, Integer>(null);
107         Assert.assertEquals("entry containing null is equal to another entry containing null", containsNull, otherContainsNull);
108 
109     }
110 
111     /**
112      * ...
113      * @param map Navigablemap&lt;Integer, Integer&gt;; map
114      * @param imMap ImmutabletreeMap&lt;Integer, Integer&gt;; immutable map
115      * @param copyOrWrap Immutable;
116      */
117     private void testIntMap(final NavigableMap<Integer, Integer> map, final ImmutableTreeMap<Integer, Integer> imMap,
118             final Immutable copyOrWrap)
119     {
120         Assert.assertTrue(map.size() == 10);
121         Assert.assertTrue(imMap.size() == 10);
122         for (int i = 0; i < 10; i++)
123         {
124             Assert.assertTrue(imMap.containsKey(i + 1));
125         }
126         for (int i = 0; i < 10; i++)
127         {
128             Assert.assertTrue(imMap.containsValue(100 * (i + 1)));
129         }
130         Assert.assertFalse(imMap.isEmpty());
131         Assert.assertFalse(imMap.containsKey(15));
132         Assert.assertFalse(imMap.containsValue(1500));
133 
134         Assert.assertTrue(imMap.keySet().size() == 10);
135         Assert.assertTrue(imMap.values().size() == 10);
136         Assert.assertTrue(imMap.keySet().first() == 1);
137         Assert.assertTrue(imMap.keySet().last() == 10);
138         Assert.assertTrue(imMap.values().contains(200));
139 
140         Assert.assertArrayEquals(map.keySet().toArray(), imMap.keySet().toSet().toArray());
141         Assert.assertArrayEquals(map.values().toArray(), imMap.values().toSet().toArray());
142         Assert.assertArrayEquals(map.keySet().toArray(), imMap.keySet().toSet().toArray()); // cached
143         Assert.assertArrayEquals(map.values().toArray(), imMap.values().toSet().toArray());
144 
145         Assert.assertTrue(checkEntrySets(map.entrySet(), imMap.entrySet().toSet()));
146         Assert.assertTrue(checkEntrySets(map.entrySet(), imMap.entrySet().toSet())); // cached
147 
148         if (copyOrWrap == Immutable.COPY)
149         {
150             Assert.assertTrue(imMap.isCopy());
151             Assert.assertTrue(imMap.toMap().equals(map));
152             Assert.assertFalse(imMap.toMap() == map);
153         }
154         else
155         {
156             Assert.assertTrue(imMap.isWrap());
157             Assert.assertTrue(imMap.toMap().equals(map));
158             Assert.assertFalse(imMap.toMap() == map); // this WRAP method returns a NEW list
159         }
160 
161         Map<Integer, Integer> to = imMap.toMap();
162         Assert.assertTrue(map.equals(to));
163 
164         // modify the underlying data structure
165         map.put(11, 1100);
166         if (copyOrWrap == Immutable.COPY)
167         {
168             Assert.assertTrue(imMap.size() == 10);
169         }
170         else
171         {
172             Assert.assertTrue(imMap.size() == 11);
173         }
174     }
175 
176     /**
177      * Determine if two entry sets contain the same keys and corresponding values.
178      * @param es Set&lt;Entry&lt;Integer, Integer&gt;&gt;; entry set
179      * @param ies Set&gt;ImmutableEntry&lt;Integer, Integer&gt;&gt;; immutable entry set
180      * @return boolean; true if the sets contain the same keys and corresponding values
181      */
182     private boolean checkEntrySets(final Set<Entry<Integer, Integer>> es, final Set<ImmutableEntry<Integer, Integer>> ies)
183     {
184         if (es.size() != ies.size())
185         {
186             return false;
187         }
188         Iterator<Entry<Integer, Integer>> entryIt = es.iterator();
189         Iterator<ImmutableEntry<Integer, Integer>> immEntryIt = ies.iterator();
190         while (entryIt.hasNext())
191         {
192             Entry<Integer, Integer> e1 = entryIt.next();
193             ImmutableEntry<Integer, Integer> e2 = immEntryIt.next();
194             if (!e1.getKey().equals(e2.getKey()) || !e1.getValue().equals(e2.getValue()))
195             {
196                 return false;
197             }
198         }
199         return true;
200     }
201 }