
cat.inspiracio.util.BagMap Maven / Gradle / Ivy
Show all versions of url-parser Show documentation
/*
Copyright 2015 Alexander Bunkenburg
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cat.inspiracio.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/** Like a map, but entries conserve their order and there may be several
* entries with the same key.
*
* A value cannot be null.
*
* Keys and values have to serialisable, because I am interested in serialisable things. */
public class BagMap implements Iterable>, Serializable {
private static final long serialVersionUID = 2587845281426723243L;
// state ------------------------------------
private final List> entries=new ArrayList>();
// construction ----------------------------
/** Makes a new empty bag map. */
public BagMap(){}
// business --------------------------------
/** Adds an entry. If the value is null, removes the parameter.
* Returns this, for fluid style.
* @param key ...
* @param value ...
* @return ... */
public BagMap add(K key, V value){
if(value==null){
remove(key);
return this;
}
Entry entry=new EntryBean(key, value);
entries.add(entry);
return this;
}
/** Gets the value of the first entry with that key, or null if there is none.
* @param key ...
* @return ... */
public V get(K key){
for(Entry entry : entries){
if(equals(key, entry.getKey()))
return entry.getValue();
}
return null;
}
/** Gets all the values for a key, in the order that they were inserted.
* Returns a fresh list.
* @param key ...
* @return ... */
public List getValues(K key){
Listvalues=new ArrayList();
for(Entry entry : entries){
K k=entry.getKey();
if(equals(key, k))
values.add(entry.getValue());
}
return values;
}
/** Is there an entry with this key?
* @param key ...
* @return ... */
public boolean containsKey(K key){
for(Entry entry : entries){
K k=entry.getKey();
if(equals(key, k))return true;
}
return false;
}
/** Removes all entries with this key.
* @param key ... */
public void remove(K key){
entries.removeIf(entry -> equals(key, entry.getKey()));
}
/** Sets the first entry with this key to this value and removes all the others.
* If there is no such entry, adds one.
*
* Setting a value to null is removing all.
* @param key ...
* @param value ... */
public void set(K key, V value){
if(value==null){
remove(key);
return;
}
boolean set=false;
Iterator>it=entries.iterator();
while(it.hasNext()){
Entry entry=it.next();
if(equals(key, entry.getKey())){
if(set){
it.remove();
}else{
entry.setValue(value);
set=true;
}
}
}
if(!set)
add(key, value);
}
public boolean isEmpty(){return entries.isEmpty();}
public boolean empty(){return isEmpty();}
/** All the entries in the order they were inserted. */
@Override public Iterator> iterator(){return entries.iterator();}
/** @return All the entries in the order they were inserted. */
public Iterable> iteratable(){return entries;}
/** @return All keys that have a value. */
public Collectionkeys(){
Setkeys=new LinkedHashSet();
for(Entry entry : entries){
K key=entry.getKey();
keys.add(key);
}
return keys;
}
/** @return All values. */
public Collectionvalues(){
Setvalues=new LinkedHashSet();
for(Entry entry : entries){
V v=entry.getValue();
values.add(v);
}
return values;
}
/** @return All entries. */
public Collection>entries(){return entries;}
// helpers -----------------------------------------------
/** Equality without stumbling over null. */
private boolean equals(K a, K b){
if(a==null)
return b==null;
return a.equals(b);
}
/** Implementation of interface Entry that is serialisable. */
private static class EntryBean implements Entry, Serializable{
private static final long serialVersionUID = -2527497268655890130L;
private K key;
private V value;
EntryBean(K k, V v){key=k; value=v;}
@Override public K getKey(){return key;}
@Override public V getValue(){return value;}
@Override public V setValue(V v){
V old=value;
value=v;
return old;
}
/** Just for debug. */
@Override public String toString(){
return key + "->" + value;
}
}
}