today
[ephemerata.git] / KezvhLib / src-lib / net / kezvh / collections / Map2 / AbstractMap2.java
bloba6cab3aba295d33bcf5a3e3f420471628f5fc0fe
1 package net.kezvh.collections.Map2;
3 import java.util.AbstractMap;
4 import java.util.Collection;
5 import java.util.Iterator;
6 import java.util.Map;
7 import java.util.Set;
9 import net.kezvh.collections.Pair;
10 import net.kezvh.collections.views.ConditionalSetView;
11 import net.kezvh.collections.views.SetView;
12 import net.kezvh.functional.lambda.L1;
13 import net.kezvh.functional.lambda.Predicate1;
15 /**
16 * @author mjacob
17 * @param <K1> key 1 type
18 * @param <K2> key 2 type
19 * @param <V> value type
21 public abstract class AbstractMap2<K1, K2, V> extends AbstractMap<Pair<K1, K2>, V> implements Map2<K1, K2, V> {
22 private static final class AbstractCouple<K1, K2> implements Pair<K1, K2> {
23 private final K1 key1;
24 private final K2 key2;
26 public AbstractCouple(final K1 key1, final K2 key2) {
27 super();
28 this.key1 = key1;
29 this.key2 = key2;
32 @Override
33 public K1 get1() {
34 return this.key1;
37 @Override
38 public K2 get2() {
39 return this.key2;
43 @Override
44 public boolean containsKey(final K1 key1, final K2 key2) {
45 return this.containsKey(new AbstractCouple<K1, K2>(key1, key2));
48 private final class K1Filter implements Predicate1<Map.Entry<Pair<K1, K2>, V>> {
49 private final K1 key1;
51 public K1Filter(final K1 key1) {
52 this.key1 = key1;
55 public Boolean op(final Map.Entry<Pair<K1, K2>, V> entry) {
56 return this.key1.equals(entry.getKey().get1());
60 private final class K2Filter implements Predicate1<Map.Entry<Pair<K1, K2>, V>> {
61 private final K2 key2;
63 public K2Filter(final K2 key2) {
64 this.key2 = key2;
67 public Boolean op(final Map.Entry<Pair<K1, K2>, V> entry) {
68 return this.key2.equals(entry.getKey().get2());
72 private final L1<Map2.Entry<K1, K2, V>, Map.Entry<Pair<K1, K2>, V>> ENTRY_CONVERTER = new L1<Map2.Entry<K1, K2, V>, Map.Entry<Pair<K1, K2>, V>>() {
73 @Override
74 public Map2.Entry<K1, K2, V> op(final Map.Entry<Pair<K1, K2>, V> param) {
75 return new Map2.Entry<K1, K2, V>() {
76 @Override
77 public Pair<K1, K2> getKey() {
78 return param.getKey();
81 @Override
82 public K1 getKey1() {
83 return param.getKey().get1();
86 @Override
87 public K2 getKey2() {
88 return param.getKey().get2();
91 @Override
92 public V getValue() {
93 return param.getValue();
96 public V setValue(final V value) {
97 return param.setValue(value);
100 @Override
101 public int hashCode() {
102 return param.hashCode();
105 @Override
106 public boolean equals(final Object obj) {
107 if (obj == null)
108 return false;
109 if (obj == this)
110 return true;
111 if (this.getClass() != obj.getClass())
112 return false;
114 final Map2.Entry<?, ?, ?> other = (Map2.Entry<?, ?, ?>) obj;
115 return this.getKey1().equals(other.getKey1()) && this.getKey2().equals(other.getKey2());
121 @Override
122 public Set<Map2.Entry<K1, K2, V>> entrySetOnKey1(final K1 key1) {
123 final Set<Map.Entry<Pair<K1, K2>, V>> filtered = new ConditionalSetView<Map.Entry<Pair<K1, K2>, V>>(new K1Filter(key1), this.entrySet());
124 return new SetView<Map.Entry<Pair<K1, K2>, V>, Map2.Entry<K1, K2, V>>(filtered, this.ENTRY_CONVERTER);
127 @Override
128 public Set<Map2.Entry<K1, K2, V>> entrySetOnKey2(final K2 key2) {
129 final Set<Map.Entry<Pair<K1, K2>, V>> filtered = new ConditionalSetView<Map.Entry<Pair<K1, K2>, V>>(new K2Filter(key2), this.entrySet());
130 return new SetView<Map.Entry<Pair<K1, K2>, V>, Map2.Entry<K1, K2, V>>(filtered, this.ENTRY_CONVERTER);
133 @Override
134 public V get(final K1 key1, final K2 key2) {
135 for (final Map.Entry<Pair<K1, K2>, V> entry : this.entrySet())
136 if (key1.equals(entry.getKey().get1()) && key2.equals(entry.getKey().get2()))
137 return entry.getValue();
138 return null;
141 private final L1<K2, Map2.Entry<K1, K2, V>> K2VIEW = new L1<K2, Map2.Entry<K1, K2, V>>() {
142 @Override
143 public K2 op(final net.kezvh.collections.Map2.Map2.Entry<K1, K2, V> param) {
144 return param.getKey2();
148 private final L1<K1, Map2.Entry<K1, K2, V>> K1VIEW = new L1<K1, Map2.Entry<K1, K2, V>>() {
149 @Override
150 public K1 op(final net.kezvh.collections.Map2.Map2.Entry<K1, K2, V> param) {
151 return param.getKey1();
155 private final L1<V, Map2.Entry<K1, K2, V>> VVIEW = new L1<V, Map2.Entry<K1, K2, V>>() {
156 @Override
157 public V op(final net.kezvh.collections.Map2.Map2.Entry<K1, K2, V> param) {
158 return param.getValue();
162 @Override
163 public Set<K2> keySetOnKey1(final K1 key1) {
164 return new SetView<Map2.Entry<K1, K2, V>, K2>(this.entrySetOnKey1(key1), this.K2VIEW);
167 @Override
168 public Set<K1> keySetOnKey2(final K2 key2) {
169 return new SetView<Map2.Entry<K1, K2, V>, K1>(this.entrySetOnKey2(key2), this.K1VIEW);
172 @Override
173 public V put(final K1 key1, final K2 key2, final V value) {
174 throw new UnsupportedOperationException();
178 * (non-Javadoc)
179 * @see java.util.AbstractMap#put(java.lang.Object, java.lang.Object)
181 @Override
182 public V put(final net.kezvh.collections.Pair<K1, K2> key, final V value) {
183 return this.put(key.get1(), key.get2(), value);
186 @Override
187 public void putAll(final Map2<? extends K1, ? extends K2, ? extends V> m) {
188 for (final Map.Entry<Pair<K1, K2>, V> entry : this.entrySet())
189 this.put(entry.getKey(), entry.getValue());
192 @Override
193 public V remove(final K1 key1, final K2 key2) {
194 for (final Iterator<Map.Entry<Pair<K1, K2>, V>> i = this.entrySet().iterator(); i.hasNext();) {
195 final Map.Entry<Pair<K1, K2>, V> entry = i.next();
196 if (key1.equals(entry.getKey().get1()) && key2.equals(entry.getKey().get2())) {
197 i.remove();
198 return entry.getValue();
201 return null;
204 @Override
205 public Collection<V> valuesOnKey1(final K1 key1) {
206 return new SetView<Map2.Entry<K1, K2, V>, V>(this.entrySetOnKey1(key1), this.VVIEW);
209 @Override
210 public Collection<V> valuesOnKey2(final K2 key2) {
211 return new SetView<Map2.Entry<K1, K2, V>, V>(this.entrySetOnKey2(key2), this.VVIEW);