1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ********************************************************************** 6 * Copyright (c) 2002-2015, International Business Machines 7 * Corporation and others. All Rights Reserved. 8 ********************************************************************** 9 * Author: Mark Davis 10 ********************************************************************** 11 */ 12 package ohos.global.icu.impl; 13 14 import java.lang.reflect.Constructor; 15 import java.util.Arrays; 16 import java.util.Collection; 17 import java.util.Collections; 18 import java.util.Comparator; 19 import java.util.HashMap; 20 import java.util.LinkedHashSet; 21 import java.util.Map; 22 import java.util.Map.Entry; 23 import java.util.Set; 24 25 import ohos.global.icu.util.Freezable; 26 27 /** 28 * A Relation is a set of mappings from keys to values. 29 * Unlike Map, there is not guaranteed to be a single value per key. 30 * The Map-like APIs return collections for values. 31 * @author medavis 32 * @hide exposed on OHOS 33 34 */ 35 public class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add , Map<K, Collection<V>>, but requires API changes 36 private Map<K, Set<V>> data; 37 38 Constructor<? extends Set<V>> setCreator; 39 Object[] setComparatorParam; 40 of(Map<K, Set<V>> map, Class<?> setCreator)41 public static <K, V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator) { 42 return new Relation<>(map, setCreator); 43 } 44 of(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator)45 public static <K,V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator) { 46 return new Relation<>(map, setCreator, setComparator); 47 } 48 Relation(Map<K, Set<V>> map, Class<?> setCreator)49 public Relation(Map<K, Set<V>> map, Class<?> setCreator) { 50 this(map, setCreator, null); 51 } 52 53 @SuppressWarnings("unchecked") Relation(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator)54 public Relation(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator) { 55 try { 56 setComparatorParam = setComparator == null ? null : new Object[]{setComparator}; 57 if (setComparator == null) { 58 this.setCreator = ((Class<? extends Set<V>>)setCreator).getConstructor(); 59 this.setCreator.newInstance(setComparatorParam); // check to make sure compiles 60 } else { 61 this.setCreator = ((Class<? extends Set<V>>)setCreator).getConstructor(Comparator.class); 62 this.setCreator.newInstance(setComparatorParam); // check to make sure compiles 63 } 64 data = map == null ? new HashMap<K, Set<V>>() : map; 65 } catch (Exception e) { 66 throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); 67 } 68 } 69 clear()70 public void clear() { 71 data.clear(); 72 } 73 containsKey(Object key)74 public boolean containsKey(Object key) { 75 return data.containsKey(key); 76 } 77 containsValue(Object value)78 public boolean containsValue(Object value) { 79 for (Set<V> values : data.values()) { 80 if (values.contains(value)) { 81 return true; 82 } 83 } 84 return false; 85 } 86 entrySet()87 public final Set<Entry<K, V>> entrySet() { 88 return keyValueSet(); 89 } 90 keyValuesSet()91 public Set<Entry<K, Set<V>>> keyValuesSet() { 92 return data.entrySet(); 93 } 94 keyValueSet()95 public Set<Entry<K, V>> keyValueSet() { 96 Set<Entry<K, V>> result = new LinkedHashSet<>(); 97 for (K key : data.keySet()) { 98 for (V value : data.get(key)) { 99 result.add(new SimpleEntry<>(key, value)); 100 } 101 } 102 return result; 103 } 104 105 @Override equals(Object o)106 public boolean equals(Object o) { 107 if (o == null) 108 return false; 109 if (o.getClass() != this.getClass()) 110 return false; 111 return data.equals(((Relation<?, ?>) o).data); 112 } 113 114 // public V get(Object key) { 115 // Set<V> set = data.get(key); 116 // if (set == null || set.size() == 0) 117 // return null; 118 // return set.iterator().next(); 119 // } 120 getAll(Object key)121 public Set<V> getAll(Object key) { 122 return data.get(key); 123 } 124 get(Object key)125 public Set<V> get(Object key) { 126 return data.get(key); 127 } 128 129 @Override hashCode()130 public int hashCode() { 131 return data.hashCode(); 132 } 133 isEmpty()134 public boolean isEmpty() { 135 return data.isEmpty(); 136 } 137 keySet()138 public Set<K> keySet() { 139 return data.keySet(); 140 } 141 put(K key, V value)142 public V put(K key, V value) { 143 Set<V> set = data.get(key); 144 if (set == null) { 145 data.put(key, set = newSet()); 146 } 147 set.add(value); 148 return value; 149 } 150 putAll(K key, Collection<? extends V> values)151 public V putAll(K key, Collection<? extends V> values) { 152 Set<V> set = data.get(key); 153 if (set == null) { 154 data.put(key, set = newSet()); 155 } 156 set.addAll(values); 157 return values.size() == 0 ? null : values.iterator().next(); 158 } 159 putAll(Collection<K> keys, V value)160 public V putAll(Collection<K> keys, V value) { 161 V result = null; 162 for (K key : keys) { 163 result = put(key, value); 164 } 165 return result; 166 } 167 newSet()168 private Set<V> newSet() { 169 try { 170 return setCreator.newInstance(setComparatorParam); 171 } catch (Exception e) { 172 throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); 173 } 174 } 175 putAll(Map<? extends K, ? extends V> t)176 public void putAll(Map<? extends K, ? extends V> t) { 177 for (Map.Entry<? extends K, ? extends V> entry : t.entrySet()) { 178 put(entry.getKey(), entry.getValue()); 179 } 180 } 181 putAll(Relation<? extends K, ? extends V> t)182 public void putAll(Relation<? extends K, ? extends V> t) { 183 for (K key : t.keySet()) { 184 for (V value : t.getAll(key)) { 185 put(key, value); 186 } 187 } 188 } 189 removeAll(K key)190 public Set<V> removeAll(K key) { 191 try { 192 return data.remove(key); 193 } catch (NullPointerException e) { 194 return null; // data doesn't allow null, eg ConcurrentHashMap 195 } 196 } 197 remove(K key, V value)198 public boolean remove(K key, V value) { 199 try { 200 Set<V> set = data.get(key); 201 if (set == null) { 202 return false; 203 } 204 boolean result = set.remove(value); 205 if (set.size() == 0) { 206 data.remove(key); 207 } 208 return result; 209 } catch (NullPointerException e) { 210 return false; // data doesn't allow null, eg ConcurrentHashMap 211 } 212 } 213 size()214 public int size() { 215 return data.size(); 216 } 217 values()218 public Set<V> values() { 219 return values(new LinkedHashSet<V>()); 220 } 221 values(C result)222 public <C extends Collection<V>> C values(C result) { 223 for (Entry<K, Set<V>> keyValue : data.entrySet()) { 224 result.addAll(keyValue.getValue()); 225 } 226 return result; 227 } 228 229 @Override toString()230 public String toString() { 231 return data.toString(); 232 } 233 234 static class SimpleEntry<K, V> implements Entry<K, V> { 235 K key; 236 237 V value; 238 SimpleEntry(K key, V value)239 public SimpleEntry(K key, V value) { 240 this.key = key; 241 this.value = value; 242 } 243 SimpleEntry(Entry<K, V> e)244 public SimpleEntry(Entry<K, V> e) { 245 this.key = e.getKey(); 246 this.value = e.getValue(); 247 } 248 249 @Override getKey()250 public K getKey() { 251 return key; 252 } 253 254 @Override getValue()255 public V getValue() { 256 return value; 257 } 258 259 @Override setValue(V value)260 public V setValue(V value) { 261 V oldValue = this.value; 262 this.value = value; 263 return oldValue; 264 } 265 } 266 addAllInverted(Relation<V,K> source)267 public Relation<K,V> addAllInverted(Relation<V,K> source) { 268 for (V value : source.data.keySet()) { 269 for (K key : source.data.get(value)) { 270 put(key, value); 271 } 272 } 273 return this; 274 } 275 addAllInverted(Map<V,K> source)276 public Relation<K,V> addAllInverted(Map<V,K> source) { 277 for (Map.Entry<V,K> entry : source.entrySet()) { 278 put(entry.getValue(), entry.getKey()); 279 } 280 return this; 281 } 282 283 volatile boolean frozen = false; 284 285 @Override isFrozen()286 public boolean isFrozen() { 287 return frozen; 288 } 289 290 @Override freeze()291 public Relation<K, V> freeze() { 292 if (!frozen) { 293 // does not handle one level down, so we do that on a case-by-case basis 294 for (K key : data.keySet()) { 295 data.put(key, Collections.unmodifiableSet(data.get(key))); 296 } 297 // now do top level 298 data = Collections.unmodifiableMap(data); 299 frozen = true; 300 } 301 return this; 302 } 303 304 @Override cloneAsThawed()305 public Relation<K, V> cloneAsThawed() { 306 // TODO do later 307 throw new UnsupportedOperationException(); 308 } 309 removeAll(Relation<K, V> toBeRemoved)310 public boolean removeAll(Relation<K, V> toBeRemoved) { 311 boolean result = false; 312 for (K key : toBeRemoved.keySet()) { 313 try { 314 Set<V> values = toBeRemoved.getAll(key); 315 if (values != null) { 316 result |= removeAll(key, values); 317 } 318 } catch (NullPointerException e) { 319 // data doesn't allow null, eg ConcurrentHashMap 320 } 321 } 322 return result; 323 } 324 325 @SafeVarargs 326 @SuppressWarnings("varargs") // Not supported by Eclipse, but we need this for javac removeAll(K... keys)327 public final Set<V> removeAll(K... keys) { 328 return removeAll(Arrays.asList(keys)); 329 } 330 removeAll(K key, Iterable<V> toBeRemoved)331 public boolean removeAll(K key, Iterable<V> toBeRemoved) { 332 boolean result = false; 333 for (V value : toBeRemoved) { 334 result |= remove(key, value); 335 } 336 return result; 337 } 338 removeAll(Collection<K> toBeRemoved)339 public Set<V> removeAll(Collection<K> toBeRemoved) { 340 Set<V> result = new LinkedHashSet<>(); 341 for (K key : toBeRemoved) { 342 try { 343 final Set<V> removals = data.remove(key); 344 if (removals != null) { 345 result.addAll(removals); 346 } 347 } catch (NullPointerException e) { 348 // data doesn't allow null, eg ConcurrentHashMap 349 } 350 } 351 return result; 352 } 353 } 354