📄 multiplevaluemap.java
字号:
/*Copyright (c) 2006-2007, Dennis M. SosnoskiAll rights reserved.Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FORANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/package org.jibx.binding.util;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Set;/** * Map supporting multiple values for a single key. The multiple value concept * doesn't really fit with the standard collections idea of a map, so this * provides its own variation of a map interface rather than extend the standard * one. * * @author Dennis M. Sosnoski */public class MultipleValueMap{ /** Backing map from key to value or array of values. */ private final HashMap m_backingMap; /** Actual number of values (not keys) present in map. */ private int m_valueCount; /** Last lookup key (<code>null</code> if none, or if value changed). */ private Object m_lastKey; /** Last lookup value (<code>null</code> if none, or if value changed). */ private Object m_lastValue; /** * Constructor. */ public MultipleValueMap() { super(); m_backingMap = new HashMap(); } /** * Internal cached lookup. * * @param key * @return value */ private Object getMapped(Object key) { if (key != m_lastKey) { m_lastKey = key; m_lastValue = m_backingMap.get(key); } return m_lastValue; } /** * Clear all entries. */ public void clear() { m_backingMap.clear(); m_valueCount = 0; } /** * Get number of values present for key. * * @param key * @return value count */ public int getCount(Object key) { Object obj = getMapped(key); if (obj instanceof MultipleValueList) { return ((MultipleValueList)obj).size(); } else if (obj == null) { return 0; } else { return 1; } } /** * Get indexed value for key. * * @param key * @param index * @return value */ public Object get(Object key, int index) { Object obj = getMapped(key); if (obj instanceof MultipleValueList) { return ((MultipleValueList)obj).get(index); } else if (obj == null) { throw new IndexOutOfBoundsException("No value present for key"); } else if (index == 0) { return obj; } else { throw new IndexOutOfBoundsException("Only one value present for key"); } } /** * Add value for key. * * @param key * @param value */ public void add(Object key, Object value) { // first force caching of current value getMapped(key); // update value as appropriate if (m_lastValue == null) { m_backingMap.put(key, value); m_lastValue = value; } else if (m_lastValue instanceof MultipleValueList) { ((MultipleValueList)m_lastValue).add(value); } else { MultipleValueList list = new MultipleValueList(); list.add(m_lastValue); list.add(value); m_backingMap.put(key, list); m_lastValue = list; } m_valueCount++; } /** * Extract all values for key. This removes the value(s) from the map and * returns them in the form of a list. * * @param key * @return prior list of values */ public List extract(Object key) { Object obj = m_backingMap.remove(key); if (key == m_lastKey) { m_lastKey = null; m_lastValue = null; } if (obj instanceof MultipleValueList) { return (MultipleValueList)obj; } else if (obj == null) { return Collections.EMPTY_LIST; } else { MultipleValueList list = new MultipleValueList(); list.add(obj); return list; } } /** * Get number of keys. * * @return key count */ public int keySize() { return m_backingMap.size(); } /** * Get number of values. * * @return value count */ public int valueSize() { return m_valueCount; } // // Delegated methods /** * Check key present in map. * * @param key * @return key present flag */ public boolean containsKey(Object key) { return m_backingMap.containsKey(key); } /** * Check if map is empty. * * @return empty flag */ public boolean isEmpty() { return m_backingMap.isEmpty(); } /** * Get key set. * * @return set of keys */ public Set keySet() { return m_backingMap.keySet(); } /** * List used for multiple values. This is just a marker, so that the actual * values can be anything at all (including lists). */ private class MultipleValueList extends ArrayList { public MultipleValueList() {} }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -