001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.util.collections;
018
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024/**
025 * A simple multimap
026 * 
027 * @author igor
028 * @param <K>
029 * @param <V>
030 */
031public class MultiMap<K, V> extends HashMap<K, List<V>>
032{
033        private static final long serialVersionUID = 1L;
034
035        /**
036         * Constructor
037         * 
038         * @see HashMap#HashMap()
039         */
040        public MultiMap()
041        {
042        }
043
044        /**
045         * Constructor
046         * 
047         * @param initialCapacity
048         * @param loadFactor
049         * 
050         * @see HashMap#HashMap(int, float)
051         */
052        public MultiMap(final int initialCapacity, final float loadFactor)
053        {
054                super(initialCapacity, loadFactor);
055        }
056
057        /**
058         * Constructor
059         * 
060         * @param initialCapacity
061         * 
062         * @see HashMap#HashMap(int)
063         */
064        public MultiMap(final int initialCapacity)
065        {
066                super(initialCapacity);
067        }
068
069        /**
070         * Constructor
071         * 
072         * @param m
073         * 
074         * @see HashMap#HashMap(Map)
075         */
076        public MultiMap(final Map<? extends K, ? extends List<V>> m)
077        {
078                super(m);
079        }
080
081        /**
082         * Adds value to the specified key
083         * 
084         * @param key
085         * @param value
086         */
087        public void addValue(final K key, final V value)
088        {
089                List<V> list = get(key);
090                if (list == null)
091                {
092                        list = new ArrayList<>(1);
093                        put(key, list);
094                }
095                list.add(value);
096        }
097
098        /**
099         * Removes value from the specified key
100         * 
101         * @param key
102         * @param value
103         */
104        public void removeValue(final K key, final V value)
105        {
106                List<V> list = get(key);
107                if (list != null)
108                {
109                        list.remove(value);
110                }
111        }
112
113        /**
114         * Replaces all existing values with the specified value. If no values exist for the key the
115         * value will be added.
116         * 
117         * @param key
118         * @param value
119         */
120        public void replaceValues(final K key, final V value)
121        {
122                List<V> list = get(key);
123                if (list != null)
124                {
125                        list.clear();
126                        list.add(value);
127                }
128                else
129                {
130                        addValue(key, value);
131                }
132        }
133
134        /**
135         * Gets the first value in the value list
136         * 
137         * @param key
138         * @return first value
139         */
140        public V getFirstValue(final K key)
141        {
142                List<V> list = get(key);
143                if ((list != null) && !list.isEmpty())
144                {
145                        return list.get(0);
146                }
147                return null;
148        }
149}