12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (c) 2002-2015, International Business Machines 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Corporation and others. All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Author: Mark Davis 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ********************************************************************** 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.lang.reflect.Constructor; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Arrays; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collection; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Comparator; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashMap; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.LinkedHashSet; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map.Entry; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Set; 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Freezable; 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A Relation is a set of mappings from keys to values. 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Unlike Map, there is not guaranteed to be a single value per key. 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The Map-like APIs return collections for values. 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author medavis 32836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 331537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class Relation<K, V> implements Freezable<Relation<K,V>> { // TODO: add , Map<K, Collection<V>>, but requires API changes 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Map<K, Set<V>> data; 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Constructor<? extends Set<V>> setCreator; 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] setComparatorParam; 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static <K, V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator) { 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Relation<K, V>(map, setCreator); 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static <K,V> Relation<K, V> of(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator) { 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new Relation<K, V>(map, setCreator, setComparator); 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation(Map<K, Set<V>> map, Class<?> setCreator) { 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(map, setCreator, null); 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("unchecked") 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation(Map<K, Set<V>> map, Class<?> setCreator, Comparator<V> setComparator) { 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setComparatorParam = setComparator == null ? null : new Object[]{setComparator}; 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (setComparator == null) { 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.setCreator = ((Class<? extends Set<V>>)setCreator).getConstructor(); 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.setCreator.newInstance(setComparatorParam); // check to make sure compiles 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.setCreator = ((Class<? extends Set<V>>)setCreator).getConstructor(Comparator.class); 62f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert this.setCreator.newInstance(setComparatorParam); // check to make sure compiles 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data = map == null ? new HashMap<K, Set<V>>() : map; 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (Exception e) { 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void clear() { 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.clear(); 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean containsKey(Object key) { 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.containsKey(key); 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean containsValue(Object value) { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (Set<V> values : data.values()) { 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (values.contains(value)) { 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final Set<Entry<K, V>> entrySet() { 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return keyValueSet(); 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 90f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<Entry<K, Set<V>>> keyValuesSet() { 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.entrySet(); 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 94f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<Entry<K, V>> keyValueSet() { 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<Entry<K, V>> result = new LinkedHashSet<Entry<K, V>>(); 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : data.keySet()) { 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (V value : data.get(key)) { 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.add(new SimpleEntry<K, V>(key, value)); 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 105f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean equals(Object o) { 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (o == null) 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (o.getClass() != this.getClass()) 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.equals(((Relation<?, ?>) o).data); 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // public V get(Object key) { 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set<V> set = data.get(key); 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if (set == null || set.size() == 0) 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // return null; 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // return set.iterator().next(); 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // } 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> getAll(Object key) { 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.get(key); 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> get(Object key) { 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.get(key); 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 129f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int hashCode() { 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.hashCode(); 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean isEmpty() { 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.isEmpty(); 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<K> keySet() { 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.keySet(); 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public V put(K key, V value) { 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<V> set = data.get(key); 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (set == null) { 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.put(key, set = newSet()); 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set.add(value); 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return value; 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public V putAll(K key, Collection<? extends V> values) { 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<V> set = data.get(key); 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (set == null) { 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.put(key, set = newSet()); 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set.addAll(values); 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return values.size() == 0 ? null : values.iterator().next(); 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public V putAll(Collection<K> keys, V value) { 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller V result = null; 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : keys) { 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = put(key, value); 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Set<V> newSet() { 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 170f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert return setCreator.newInstance(setComparatorParam); 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (Exception e) { 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw (RuntimeException) new IllegalArgumentException("Can't create new set").initCause(e); 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void putAll(Map<? extends K, ? extends V> t) { 177f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert for (Map.Entry<? extends K, ? extends V> entry : t.entrySet()) { 178f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert put(entry.getKey(), entry.getValue()); 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void putAll(Relation<? extends K, ? extends V> t) { 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : t.keySet()) { 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (V value : t.getAll(key)) { 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller put(key, value); 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> removeAll(K key) { 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.remove(key); 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (NullPointerException e) { 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; // data doesn't allow null, eg ConcurrentHashMap 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean remove(K key, V value) { 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<V> set = data.get(key); 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (set == null) { 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean result = set.remove(value); 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (set.size() == 0) { 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.remove(key); 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (NullPointerException e) { 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; // data doesn't allow null, eg ConcurrentHashMap 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int size() { 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.size(); 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> values() { 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return values(new LinkedHashSet<V>()); 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public <C extends Collection<V>> C values(C result) { 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (Entry<K, Set<V>> keyValue : data.entrySet()) { 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.addAll(keyValue.getValue()); 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 229f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() { 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return data.toString(); 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static class SimpleEntry<K, V> implements Entry<K, V> { 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller K key; 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller V value; 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleEntry(K key, V value) { 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.key = key; 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.value = value; 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleEntry(Entry<K, V> e) { 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.key = e.getKey(); 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.value = e.getValue(); 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 249f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public K getKey() { 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return key; 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 254f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public V getValue() { 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return value; 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 259f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public V setValue(V value) { 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller V oldValue = this.value; 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.value = value; 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return oldValue; 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation<K,V> addAllInverted(Relation<V,K> source) { 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (V value : source.data.keySet()) { 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : source.data.get(value)) { 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller put(key, value); 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation<K,V> addAllInverted(Map<V,K> source) { 277f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert for (Map.Entry<V,K> entry : source.entrySet()) { 278f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert put(entry.getValue(), entry.getKey()); 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller volatile boolean frozen = false; 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 285f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean isFrozen() { 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return frozen; 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 290f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation<K, V> freeze() { 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!frozen) { 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // does not handle one level down, so we do that on a case-by-case basis 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : data.keySet()) { 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.put(key, Collections.unmodifiableSet(data.get(key))); 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // now do top level 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data = Collections.unmodifiableMap(data); 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller frozen = true; 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return this; 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 304f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Relation<K, V> cloneAsThawed() { 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // TODO do later 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new UnsupportedOperationException(); 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean removeAll(Relation<K, V> toBeRemoved) { 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean result = false; 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : toBeRemoved.keySet()) { 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<V> values = toBeRemoved.getAll(key); 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (values != null) { 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result |= removeAll(key, values); 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (NullPointerException e) { 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // data doesn't allow null, eg ConcurrentHashMap 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> removeAll(K... keys) { 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return removeAll(Arrays.asList(keys)); 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean removeAll(K key, Iterable<V> toBeRemoved) { 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean result = false; 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (V value : toBeRemoved) { 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result |= remove(key, value); 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Set<V> removeAll(Collection<K> toBeRemoved) { 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Set<V> result = new LinkedHashSet<V>(); 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (K key : toBeRemoved) { 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final Set<V> removals = data.remove(key); 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (removals != null) { 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.addAll(removals); 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (NullPointerException e) { 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // data doesn't allow null, eg ConcurrentHashMap 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 351f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert} 352