001/*******************************************************************************
002The MIT License (MIT)
003
004Copyright (c) 2024 KILLCODING.COM
005
006Permission is hereby granted, free of charge, to any person obtaining a copy
007of this software and associated documentation files (the "Software"), to deal
008in the Software without restriction, including without limitation the rights
009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010copies of the Software, and to permit persons to whom the Software is
011furnished to do so, subject to the following conditions:
012
013The above copyright notice and this permission notice shall be included in
014all copies or substantial portions of the Software.
015
016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
022THE SOFTWARE.
023*****************************************************************************/
024package com.killcoding.tool;
025
026import java.io.Serializable;
027import java.util.AbstractMap;
028import java.util.AbstractSet;
029import java.util.ArrayList;
030import java.util.Iterator;
031import java.util.Map;
032import java.util.Set;
033
034@SuppressWarnings("serial")
035public class ResultMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable {
036
037        static class Entry<K, V> implements Map.Entry<K, V>, Cloneable, Serializable {
038                protected K key;
039                protected V value;
040
041                public Entry(K key, V value) {
042                        this.key = key;
043                        this.value = value;
044                }
045
046                public K getKey() {
047                        return key;
048                }
049
050                public V getValue() {
051                        return value;
052                }
053
054                public V setValue(V newValue) {
055                        V oldValue = value;
056                        value = newValue;
057                        return oldValue;
058                }
059
060                public boolean equals(Object o) {
061                        if (!(o instanceof Map.Entry)) {
062                                return false;
063                        }
064                        @SuppressWarnings("unchecked")
065                        Map.Entry<K, V> e = (Map.Entry<K, V>) o;
066                        return (key == null ? e.getKey() == null : key.equals(e.getKey()))
067                                        && (value == null ? e.getValue() == null : value.equals(e.getValue()));
068                }
069
070                public int hashCode() {
071                        int keyHash = (key == null ? 0 : key.hashCode());
072                        int valueHash = (value == null ? 0 : value.hashCode());
073                        return keyHash ^ valueHash;
074                }
075
076                public String toString() {
077                        return key + "=" + value;
078                }
079        }
080
081        private Set<java.util.Map.Entry<K, V>> entries = null;
082        private ArrayList<java.util.Map.Entry<K, V>> list;
083
084        public ResultMap() {
085                super();
086                list = new ArrayList<java.util.Map.Entry<K, V>>();
087        }
088
089        public ResultMap(Map<K, V> map) {
090                super();
091                list = new ArrayList<java.util.Map.Entry<K, V>>();
092                putAll(map);
093        }
094
095        public ResultMap(int initialCapacity) {
096                super();
097                list = new ArrayList<java.util.Map.Entry<K, V>>(initialCapacity);
098        }
099
100        @Override
101        public Set<java.util.Map.Entry<K, V>> entrySet() {
102                if (entries == null) {
103                        entries = new AbstractSet<java.util.Map.Entry<K, V>>() {
104                                public void clear() {
105                                        list.clear();
106                                }
107
108                                public Iterator<java.util.Map.Entry<K, V>> iterator() {
109                                        return list.iterator();
110                                }
111
112                                public int size() {
113                                        return list.size();
114                                }
115                        };
116                }
117                return entries;
118        }
119
120        @Override
121        public V put(K key, V value) {
122                int size = list.size();
123                Entry<K, V> entry = null;
124                int i;
125                if (key == null) {
126                        for (i = 0; i < size; i++) {
127                                entry = (Entry<K, V>) (list.get(i));
128                                if (entry.getKey() == null) {
129                                        break;
130                                }
131                        }
132                } else {
133                        for (i = 0; i < size; i++) {
134                                entry = (Entry<K, V>) (list.get(i));
135                                if (key.equals(entry.getKey())) {
136                                        break;
137                                }
138                        }
139                }
140                V oldValue = null;
141                if (i < size) {
142                        oldValue = entry.getValue();
143                        entry.setValue(value);
144                } else {
145                        list.add(new Entry<K, V>(key, value));
146                }
147                return oldValue;
148        }
149
150        @Override
151        public ResultMap<K, V> clone() {
152                return new ResultMap<K, V>(this);
153        }
154
155}