blob: 3ee64b64bf9c38e181494f26289f74b77f3e7c29 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.framework.util;
import java.util.*;
/**
* Simple map when dealing with small amounts of entries.
* This class also provides a Collections view of the keys
*
* @param <K> The key type
* @param <V> the value type
*/
public class ArrayMap<K, V> implements Collection<K> {
final List<K> keys;
final List<V> values;
public ArrayMap(int initialCapacity) {
keys = new ArrayList<>(initialCapacity);
values = new ArrayList<>(initialCapacity);
}
/**
* Note that the keys and values are not copied. Changes to this ArrayMap
* will change the values of the keys and values Lists.
* @param keys
* @param values
*/
public ArrayMap(List<K> keys, List<V> values) {
if (keys.size() != values.size())
throw new IllegalArgumentException("Keys and values size must be equal."); //$NON-NLS-1$
this.keys = keys;
this.values = values;
}
public V get(K key) {
int index = keys.indexOf(key);
if (index < 0)
return null;
return values.get(index);
}
public void put(K key, V value) {
int index = keys.indexOf(key);
if (index > 0) {
values.set(index, value);
} else {
keys.add(key);
values.add(value);
}
}
public boolean remove(Object key) {
int index = keys.indexOf(key);
if (index < 0)
return false;
keys.remove(index);
values.remove(index);
return true;
}
public void clear() {
keys.clear();
values.clear();
}
public List<K> getKeys() {
return new ArrayList<>(keys);
}
public List<V> getValues() {
return new ArrayList<>(values);
}
public int size() {
return keys.size();
}
public boolean isEmpty() {
return keys.isEmpty();
}
public boolean contains(Object o) {
return keys.contains(o);
}
public Iterator<K> iterator() {
final Iterator<K> keyIter = keys.iterator();
final Iterator<V> valueIter = values.iterator();
return new Iterator<K>() {
public boolean hasNext() {
return keyIter.hasNext();
}
public K next() {
valueIter.next();
return keyIter.next();
}
public void remove() {
valueIter.remove();
keyIter.remove();
}
};
}
public Object[] toArray() {
return keys.toArray();
}
public <T> T[] toArray(T[] a) {
return keys.toArray(a);
}
public boolean add(K o) {
throw new UnsupportedOperationException();
}
public boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
public boolean addAll(Collection<? extends K> c) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> c) {
boolean result = false;
for (Object key : c)
result |= remove(key);
return result;
}
public boolean retainAll(Collection<?> c) {
boolean result = false;
Object[] keyArray = keys.toArray();
for (Object key : keyArray) {
if (!c.contains(key))
result |= remove(key);
}
return result;
}
public K getKey(int index) {
return keys.get(index);
}
public V getValue(int index) {
return values.get(index);
}
public void sort(Comparator<K> comparator) {
List<K> sortedKeys = new ArrayList<>(keys);
Collections.sort(sortedKeys, comparator);
List<V> sortedValues = new ArrayList<>(sortedKeys.size());
for (K key : sortedKeys) {
sortedValues.add(getByIdentity(key));
}
clear();
for (int i = 0; i < sortedKeys.size(); i++) {
put(sortedKeys.get(i), sortedValues.get(i));
}
}
private V getByIdentity(K key) {
int index = 0;
for (K existing : keys) {
if (existing == key)
return getValue(index);
index++;
}
return null;
}
}