• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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