1 package net
.kezvh
.collections
.DualMap
;
3 import java
.util
.AbstractMap
;
4 import java
.util
.Collection
;
5 import java
.util
.Iterator
;
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
;
17 * @param <K1> key 1 type
18 * @param <K2> key 2 type
19 * @param <V> value type
21 public abstract class AbstractDualMap
<K1
, K2
, V
> extends AbstractMap
<Pair
<K1
, K2
>, V
> implements DualMap
<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
) {
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
) {
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
) {
67 public Boolean
op(final Map
.Entry
<Pair
<K1
, K2
>, V
> entry
) {
68 return this.key2
.equals(entry
.getKey().get2());
72 private final L1
<DualMap
.Entry
<K1
, K2
, V
>, Map
.Entry
<Pair
<K1
, K2
>, V
>> ENTRY_CONVERTER
= new L1
<DualMap
.Entry
<K1
, K2
, V
>, Map
.Entry
<Pair
<K1
, K2
>, V
>>() {
74 public DualMap
.Entry
<K1
, K2
, V
> op(final Map
.Entry
<Pair
<K1
, K2
>, V
> param
) {
75 return new DualMap
.Entry
<K1
, K2
, V
>() {
77 public Pair
<K1
, K2
> getKey() {
78 return param
.getKey();
83 return param
.getKey().get1();
88 return param
.getKey().get2();
93 return param
.getValue();
96 public V
setValue(final V value
) {
97 return param
.setValue(value
);
101 public int hashCode() {
102 return param
.hashCode();
106 public boolean equals(final Object obj
) {
111 if (this.getClass() != obj
.getClass())
114 final DualMap
.Entry
<?
, ?
, ?
> other
= (DualMap
.Entry
<?
, ?
, ?
>) obj
;
115 return this.getKey1().equals(other
.getKey1()) && this.getKey2().equals(other
.getKey2());
122 public Set
<DualMap
.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
>, DualMap
.Entry
<K1
, K2
, V
>>(filtered
, this.ENTRY_CONVERTER
);
128 public Set
<DualMap
.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
>, DualMap
.Entry
<K1
, K2
, V
>>(filtered
, this.ENTRY_CONVERTER
);
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();
141 private final L1
<K2
, DualMap
.Entry
<K1
, K2
, V
>> K2VIEW
= new L1
<K2
, DualMap
.Entry
<K1
, K2
, V
>>() {
143 public K2
op(final net
.kezvh
.collections
.DualMap
.DualMap
.Entry
<K1
, K2
, V
> param
) {
144 return param
.getKey2();
148 private final L1
<K1
, DualMap
.Entry
<K1
, K2
, V
>> K1VIEW
= new L1
<K1
, DualMap
.Entry
<K1
, K2
, V
>>() {
150 public K1
op(final net
.kezvh
.collections
.DualMap
.DualMap
.Entry
<K1
, K2
, V
> param
) {
151 return param
.getKey1();
155 private final L1
<V
, DualMap
.Entry
<K1
, K2
, V
>> VVIEW
= new L1
<V
, DualMap
.Entry
<K1
, K2
, V
>>() {
157 public V
op(final net
.kezvh
.collections
.DualMap
.DualMap
.Entry
<K1
, K2
, V
> param
) {
158 return param
.getValue();
163 public Set
<K2
> keySetOnKey1(final K1 key1
) {
164 return new SetView
<DualMap
.Entry
<K1
, K2
, V
>, K2
>(this.entrySetOnKey1(key1
), this.K2VIEW
);
168 public Set
<K1
> keySetOnKey2(final K2 key2
) {
169 return new SetView
<DualMap
.Entry
<K1
, K2
, V
>, K1
>(this.entrySetOnKey2(key2
), this.K1VIEW
);
173 public V
put(final K1 key1
, final K2 key2
, final V value
) {
174 throw new UnsupportedOperationException();
179 * @see java.util.AbstractMap#put(java.lang.Object, java.lang.Object)
182 public V
put(final net
.kezvh
.collections
.Pair
<K1
, K2
> key
, final V value
) {
183 return this.put(key
.get1(), key
.get2(), value
);
187 public void putAll(final DualMap
<?
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());
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())) {
198 return entry
.getValue();
205 public Collection
<V
> valuesOnKey1(final K1 key1
) {
206 return new SetView
<DualMap
.Entry
<K1
, K2
, V
>, V
>(this.entrySetOnKey1(key1
), this.VVIEW
);
210 public Collection
<V
> valuesOnKey2(final K2 key2
) {
211 return new SetView
<DualMap
.Entry
<K1
, K2
, V
>, V
>(this.entrySetOnKey2(key2
), this.VVIEW
);