/* GENERATED SOURCE. DO NOT MODIFY. */ /* ********************************************************************** * Copyright (c) 2002-2015, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Mark Davis ********************************************************************** */ package android.icu.impl; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import android.icu.util.Freezable; /** * A Relation is a set of mappings from keys to values. * Unlike Map, there is not guaranteed to be a single value per key. * The Map-like APIs return collections for values. * @author medavis * @hide Only a subset of ICU is exposed in Android */ public class Relation implements Freezable> { // TODO: add , Map>, but requires API changes private Map> data; Constructor> setCreator; Object[] setComparatorParam; public static Relation of(Map> map, Class setCreator) { return new Relation(map, setCreator); } public static Relation of(Map> map, Class setCreator, Comparator setComparator) { return new Relation(map, setCreator, setComparator); } public Relation(Map> map, Class setCreator) { this(map, setCreator, null); } @SuppressWarnings("unchecked") public Relation(Map> map, Class setCreator, Comparator setComparator) { try { setComparatorParam = setComparator == null ? null : new Object[]{setComparator}; if (setComparator == null) { this.setCreator = ((Class>)setCreator).getConstructor(); this.setCreator.newInstance(setComparatorParam); // check to make sure compiles } else { this.setCreator = ((Class>)setCreator).getConstructor(Comparator.class); this.setCreator.newInstance(setComparatorParam); // check to make sure compiles } data = map == null ? new HashMap>() : map; } catch (Exception e) { throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); } } public void clear() { data.clear(); } public boolean containsKey(Object key) { return data.containsKey(key); } public boolean containsValue(Object value) { for (Set values : data.values()) { if (values.contains(value)) { return true; } } return false; } public final Set> entrySet() { return keyValueSet(); } public Set>> keyValuesSet() { return data.entrySet(); } public Set> keyValueSet() { Set> result = new LinkedHashSet>(); for (K key : data.keySet()) { for (V value : data.get(key)) { result.add(new SimpleEntry(key, value)); } } return result; } public boolean equals(Object o) { if (o == null) return false; if (o.getClass() != this.getClass()) return false; return data.equals(((Relation) o).data); } // public V get(Object key) { // Set set = data.get(key); // if (set == null || set.size() == 0) // return null; // return set.iterator().next(); // } public Set getAll(Object key) { return data.get(key); } public Set get(Object key) { return data.get(key); } public int hashCode() { return data.hashCode(); } public boolean isEmpty() { return data.isEmpty(); } public Set keySet() { return data.keySet(); } public V put(K key, V value) { Set set = data.get(key); if (set == null) { data.put(key, set = newSet()); } set.add(value); return value; } public V putAll(K key, Collection values) { Set set = data.get(key); if (set == null) { data.put(key, set = newSet()); } set.addAll(values); return values.size() == 0 ? null : values.iterator().next(); } public V putAll(Collection keys, V value) { V result = null; for (K key : keys) { result = put(key, value); } return result; } private Set newSet() { try { return (Set) setCreator.newInstance(setComparatorParam); } catch (Exception e) { throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); } } public void putAll(Map t) { for (K key : t.keySet()) { put(key, t.get(key)); } } public void putAll(Relation t) { for (K key : t.keySet()) { for (V value : t.getAll(key)) { put(key, value); } } } public Set removeAll(K key) { try { return data.remove(key); } catch (NullPointerException e) { return null; // data doesn't allow null, eg ConcurrentHashMap } } public boolean remove(K key, V value) { try { Set set = data.get(key); if (set == null) { return false; } boolean result = set.remove(value); if (set.size() == 0) { data.remove(key); } return result; } catch (NullPointerException e) { return false; // data doesn't allow null, eg ConcurrentHashMap } } public int size() { return data.size(); } public Set values() { return values(new LinkedHashSet()); } public > C values(C result) { for (Entry> keyValue : data.entrySet()) { result.addAll(keyValue.getValue()); } return result; } public String toString() { return data.toString(); } static class SimpleEntry implements Entry { K key; V value; public SimpleEntry(K key, V value) { this.key = key; this.value = value; } public SimpleEntry(Entry e) { this.key = e.getKey(); this.value = e.getValue(); } public K getKey() { return key; } public V getValue() { return value; } public V setValue(V value) { V oldValue = this.value; this.value = value; return oldValue; } } public Relation addAllInverted(Relation source) { for (V value : source.data.keySet()) { for (K key : source.data.get(value)) { put(key, value); } } return this; } public Relation addAllInverted(Map source) { for (V value : source.keySet()) { put(source.get(value), value); } return this; } volatile boolean frozen = false; public boolean isFrozen() { return frozen; } public Relation freeze() { if (!frozen) { // does not handle one level down, so we do that on a case-by-case basis for (K key : data.keySet()) { data.put(key, Collections.unmodifiableSet(data.get(key))); } // now do top level data = Collections.unmodifiableMap(data); frozen = true; } return this; } public Relation cloneAsThawed() { // TODO do later throw new UnsupportedOperationException(); } public boolean removeAll(Relation toBeRemoved) { boolean result = false; for (K key : toBeRemoved.keySet()) { try { Set values = toBeRemoved.getAll(key); if (values != null) { result |= removeAll(key, values); } } catch (NullPointerException e) { // data doesn't allow null, eg ConcurrentHashMap } } return result; } public Set removeAll(K... keys) { return removeAll(Arrays.asList(keys)); } public boolean removeAll(K key, Iterable toBeRemoved) { boolean result = false; for (V value : toBeRemoved) { result |= remove(key, value); } return result; } public Set removeAll(Collection toBeRemoved) { Set result = new LinkedHashSet(); for (K key : toBeRemoved) { try { final Set removals = data.remove(key); if (removals != null) { result.addAll(removals); } } catch (NullPointerException e) { // data doesn't allow null, eg ConcurrentHashMap } } return result; } }