annotate at/ofai/music/util/ArrayMap.java @ 5:bcb4c9697967 tip

Add README and CITATION files
author Chris Cannam
date Tue, 03 Dec 2013 12:58:05 +0000
parents 4c3f5bc01c97
children
rev   line source
Chris@2 1 /*
Chris@2 2 Copyright (C) 2001, 2006 by Simon Dixon
Chris@2 3
Chris@2 4 This program is free software; you can redistribute it and/or modify
Chris@2 5 it under the terms of the GNU General Public License as published by
Chris@2 6 the Free Software Foundation; either version 2 of the License, or
Chris@2 7 (at your option) any later version.
Chris@2 8
Chris@2 9 This program is distributed in the hope that it will be useful,
Chris@2 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@2 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@2 12 GNU General Public License for more details.
Chris@2 13
Chris@2 14 You should have received a copy of the GNU General Public License along
Chris@2 15 with this program (the file gpl.txt); if not, download it from
Chris@2 16 http://www.gnu.org/licenses/gpl.txt or write to the
Chris@2 17 Free Software Foundation, Inc.,
Chris@2 18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Chris@2 19 */
Chris@2 20
Chris@2 21 package at.ofai.music.util;
Chris@2 22
Chris@2 23 import java.util.ArrayList;
Chris@2 24 import java.util.Collection;
Chris@2 25 import java.util.Map;
Chris@2 26 import java.util.Set;
Chris@2 27 import java.util.TreeSet;
Chris@2 28
Chris@2 29 // An implementation of the Map interface, backed by an ArrayList, which
Chris@2 30 // preserves the elements in the order that they are added to the map.
Chris@2 31 // Operations will take linear rather than constant time (as for the efficient
Chris@2 32 // implementations of Map). Operations are not synchronized; caveat programmer!
Chris@2 33 // Used by class Parameters
Chris@2 34 // Updated to use generics; demonstrates that generics do not necessarily make
Chris@2 35 // programs more readable, simple, safe, etc.
Chris@2 36 class ArrayMap implements Map<String,Object> {
Chris@2 37
Chris@2 38 protected ArrayList<Entry> entries;
Chris@2 39
Chris@2 40 protected class Entry implements Map.Entry<String,Object>,
Chris@2 41 Comparable<Object> {
Chris@2 42 protected String key;
Chris@2 43 protected Object value;
Chris@2 44 protected Entry(String k, Object v) {
Chris@2 45 key = k;
Chris@2 46 value = v;
Chris@2 47 } // constructor
Chris@2 48 public boolean equals(Object o) {
Chris@2 49 return (o instanceof Entry) && key.equals(((Entry)o).key) &&
Chris@2 50 value.equals(((Entry)o).value);
Chris@2 51 } // equals()
Chris@2 52 public String getKey() { return key; }
Chris@2 53 public Object getValue() { return value; }
Chris@2 54 public Object setValue(Object newValue) {
Chris@2 55 Object oldValue = value;
Chris@2 56 value = newValue;
Chris@2 57 return oldValue;
Chris@2 58 } // setValue()
Chris@2 59 public int hashCode() {
Chris@2 60 return (key==null? 0 : key.hashCode()) ^
Chris@2 61 (value==null? 0 : value.hashCode());
Chris@2 62 } // hashCode()
Chris@2 63 public int compareTo(Object o) {
Chris@2 64 return key.compareTo(((Entry)o).key);
Chris@2 65 } // compareTo()
Chris@2 66 } // inner class Entry
Chris@2 67
Chris@2 68 public ArrayMap() { entries = new ArrayList<Entry>(); }//default constructor
Chris@2 69 public ArrayMap(Map<String,Object> m) { this(); putAll(m); } // copy constructor
Chris@2 70
Chris@2 71 // Returns the index of an entry, given its key, or -1 if it is not in map.
Chris@2 72 // Note that ArrayList.indexOf() can't be used, because it doesn't call
Chris@2 73 // ArrayMap$Entry.equals() [bug?? or does it call key.equals(entry)??]
Chris@2 74 public int indexOf(String key) {
Chris@2 75 for (int i = 0; i < size(); i++)
Chris@2 76 if (key.equals(entries.get(i).key))
Chris@2 77 return i;
Chris@2 78 return -1;
Chris@2 79 } // indexOf()
Chris@2 80
Chris@2 81 // Returns the map entry at the given index
Chris@2 82 public Entry getEntry(int i) { return entries.get(i); }
Chris@2 83
Chris@2 84 // Removes all mappings from this map (optional operation).
Chris@2 85 public void clear() { entries.clear(); }
Chris@2 86
Chris@2 87 // Returns true if this map contains a mapping for the specified key.
Chris@2 88 public boolean containsKey(Object key) {
Chris@2 89 return indexOf((String)key) >= 0;
Chris@2 90 } // containsKey()
Chris@2 91
Chris@2 92 // Returns true if this map maps one or more keys to the specified value.
Chris@2 93 public boolean containsValue(Object value) {
Chris@2 94 for (int i = 0; i < size(); i++)
Chris@2 95 if (value.equals(entries.get(i).value))
Chris@2 96 return true;
Chris@2 97 return false;
Chris@2 98 } // containsValue()
Chris@2 99
Chris@2 100 // Returns a set view of the mappings contained in this map.
Chris@2 101 public Set<Map.Entry<String,Object>> entrySet() {
Chris@2 102 TreeSet<Map.Entry<String,Object>> s =
Chris@2 103 new TreeSet<Map.Entry<String,Object>>();
Chris@2 104 for (int i = 0; i < size(); i++)
Chris@2 105 s.add(entries.get(i));
Chris@2 106 return s;
Chris@2 107 } // entrySet()
Chris@2 108
Chris@2 109 // Compares the specified object with this map for equality.
Chris@2 110 public boolean equals(Object o) { return (o == this); }
Chris@2 111
Chris@2 112 // Returns the value to which this map maps the specified key.
Chris@2 113 public Object get(Object key) {
Chris@2 114 int i = indexOf((String)key);
Chris@2 115 if (i == -1)
Chris@2 116 return null;
Chris@2 117 return entries.get(i).value;
Chris@2 118 } // get()
Chris@2 119
Chris@2 120 // Returns the hash code value for this map.
Chris@2 121 public int hashCode() {
Chris@2 122 int h = 0;
Chris@2 123 for (int i = 0; i < size(); i++)
Chris@2 124 h ^= entries.get(i).hashCode();
Chris@2 125 return h;
Chris@2 126 } // hashCode()
Chris@2 127
Chris@2 128 // Returns true if this map contains no key-value mappings.
Chris@2 129 public boolean isEmpty() { return entries.isEmpty(); }
Chris@2 130
Chris@2 131 // Returns a set view of the keys contained in this map.
Chris@2 132 public Set<String> keySet() {
Chris@2 133 TreeSet<String> s = new TreeSet<String>();
Chris@2 134 for (int i = 0; i < size(); i++)
Chris@2 135 s.add(entries.get(i).key);
Chris@2 136 return s;
Chris@2 137 } // keySet()
Chris@2 138
Chris@2 139 // Associates the specified value with the specified key in this map
Chris@2 140 public Object put(String key, Object value) {
Chris@2 141 int i = indexOf(key);
Chris@2 142 if (i < 0) {
Chris@2 143 entries.add(new Entry(key, value));
Chris@2 144 return null;
Chris@2 145 } else
Chris@2 146 return entries.get(i).setValue(value);
Chris@2 147 } // put()
Chris@2 148
Chris@2 149 // Copies all of the mappings from the specified map to this map
Chris@2 150 public void putAll(Map m) {
Chris@2 151 // The following warning seems to be unavoidable:
Chris@2 152 // warning: [unchecked] unchecked conversion
Chris@2 153 Map<String,Object> m1 = (Map<String,Object>)m;
Chris@2 154 for (Map.Entry<String,Object> me : m1.entrySet()) {
Chris@2 155 put(me.getKey(), me.getValue());
Chris@2 156 }
Chris@2 157 } // putAll()
Chris@2 158
Chris@2 159 // Removes the mapping for this key from this map if present
Chris@2 160 public Object remove(Object key) {
Chris@2 161 int i = indexOf((String)key);
Chris@2 162 if (i < 0)
Chris@2 163 return null;
Chris@2 164 return entries.remove(i);
Chris@2 165 } // remove()
Chris@2 166
Chris@2 167 // Returns the number of key-value mappings in this map.
Chris@2 168 public int size() { return entries.size(); }
Chris@2 169
Chris@2 170 // Returns a collection view of the values contained in this map.
Chris@2 171 public Collection<Object> values() {
Chris@2 172 ArrayList<Object> s = new ArrayList<Object>();
Chris@2 173 for (int i = 0; i < size(); i++)
Chris@2 174 s.add(entries.get(i).value);
Chris@2 175 return s;
Chris@2 176 } // values()
Chris@2 177
Chris@2 178 } // class ArrayMap