View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.keyvalue;
18  
19  import java.util.Map;
20  
21  import org.apache.commons.collections4.KeyValue;
22  
23  /**
24   * A mutable {@code KeyValue} pair that does not implement
25   * {@link java.util.Map.Entry Map.Entry}.
26   * <p>
27   * Note that a {@code DefaultKeyValue} instance may not contain
28   * itself as a key or value.
29   * </p>
30   *
31   * @param <K> the type of keys
32   * @param <V> the type of values
33   * @since 3.0
34   */
35  public class DefaultKeyValue<K, V> extends AbstractKeyValue<K, V> {
36  
37      /**
38       * Constructs a new pair with a null key and null value.
39       */
40      public DefaultKeyValue() {
41          super(null, null);
42      }
43  
44      /**
45       * Constructs a new pair with the specified key and given value.
46       *
47       * @param key  the key for the entry, may be null
48       * @param value  the value for the entry, may be null
49       */
50      public DefaultKeyValue(final K key, final V value) {
51          super(key, value);
52      }
53  
54      /**
55       * Constructs a new pair from the specified {@code KeyValue}.
56       *
57       * @param pair  the pair to copy, must not be null
58       * @throws NullPointerException if the entry is null
59       */
60      public DefaultKeyValue(final KeyValue<? extends K, ? extends V> pair) {
61          super(pair.getKey(), pair.getValue());
62      }
63  
64      /**
65       * Constructs a new pair from the specified {@code Map.Entry}.
66       *
67       * @param entry  the entry to copy, must not be null
68       * @throws NullPointerException if the entry is null
69       */
70      public DefaultKeyValue(final Map.Entry<? extends K, ? extends V> entry) {
71          super(entry.getKey(), entry.getValue());
72      }
73  
74      /**
75       * Compares this {@code Map.Entry} with another {@code Map.Entry}.
76       * <p>
77       * Returns true if the compared object is also a {@code DefaultKeyValue},
78       * and its key and value are equal to this object's key and value.
79       *
80       * @param obj  the object to compare to
81       * @return true if equal key and value
82       */
83      @Override
84      public boolean equals(final Object obj) {
85          if (obj == this) {
86              return true;
87          }
88          if (!(obj instanceof DefaultKeyValue)) {
89              return false;
90          }
91  
92          final DefaultKeyValue<?, ?> other = (DefaultKeyValue<?, ?>) obj;
93          return
94              (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) &&
95              (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
96      }
97  
98      /**
99       * Gets a hashCode compatible with the equals method.
100      * <p>
101      * Implemented per API documentation of {@link java.util.Map.Entry#hashCode()},
102      * however subclasses may override this.
103      *
104      * @return a suitable hash code
105      */
106     @Override
107     public int hashCode() {
108         return (getKey() == null ? 0 : getKey().hashCode()) ^
109                (getValue() == null ? 0 : getValue().hashCode());
110     }
111 
112     /**
113      * Sets the key.
114      *
115      * @param key  the new key
116      * @return the old key
117      * @throws IllegalArgumentException if key is this object
118      */
119     @Override
120     public K setKey(final K key) {
121         if (key == this) {
122             throw new IllegalArgumentException("DefaultKeyValue may not contain itself as a key.");
123         }
124 
125         return super.setKey(key);
126     }
127 
128     /**
129      * Sets the value.
130      *
131      * @return the old value of the value
132      * @param value the new value
133      * @throws IllegalArgumentException if value is this object
134      */
135     @Override
136     public V setValue(final V value) {
137         if (value == this) {
138             throw new IllegalArgumentException("DefaultKeyValue may not contain itself as a value.");
139         }
140 
141         return super.setValue(value);
142     }
143 
144     /**
145      * Returns a new {@code Map.Entry} object with key and value from this pair.
146      *
147      * @return a MapEntry instance
148      */
149     public Map.Entry<K, V> toMapEntry() {
150         return new DefaultMapEntry<>(this);
151     }
152 
153 }