我需要一些帮助来理解这里发生的事情。我在将元素插入 Map 时收到“IndexOutOfBoundsException”。这里是堆栈跟踪。
java.lang.IndexOutOfBoundsException: Index: 192, Size: 192
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at somepackage.SequentialMap.getKey(Unknown Source)
at somepackage.SequentialIterator.next(Unknown Source)
at java.util.HashMap.buildCache(HashMap.java:590)
at java.util.HashMap.resize(HashMap.java:576)
at java.util.HashMap.addEntry(HashMap.java:939)
at java.util.HashMap.put(HashMap.java:477)
at somepackage.SequentialMap.put(Unknown Source)
at somepackage.BatchBurstingInfo.parseContents(Unknown Source)
at somepackage.BatchBurstingInfo.parse(Unknown Source)
at somepackager.BatchBurstingInfo.setFileContents(Unknown Source)
at somepackage.BurstingListBean.setMembers(Unknown Source)
上面的 SeqentialMap 扩展了 HashMap 。
在这里,我们试图插入一个大于 200 的对象列表。问题是当我在使用 JDK 1.6 的开发设置中运行时它工作正常,但在 weblogic 服务器中,我总是在相同的步骤中得到这个异常。
另外,在调试时,我在 HashMap 类中找不到任何 buildCache 方法,这是否意味着 weblogic JDK 是一些不同版本的 og 实现。
这是代码片段
public class SequentialMap extends HashMap
{
private ArrayList m_keys = new ArrayList();
/**
* Removes the mapping for this key from this map if present.
*
* @param key key whose mapping is to be removed from the map.
* @return previous value associated with specified key, or <tt>null</tt>
* if there was no mapping for key. A <tt>null</tt> return can
* also indicate that the map previously associated <tt>null</tt>
* with the specified key.
*/
public Object remove(Object key)
{
synchronized(this)
{
if(m_keys != null)
{
int iSize = m_keys.size();
ArrayList oNewArray = new ArrayList();
for(int i = 0; i < iSize; i++)
{
if(m_keys.get(i).equals(key) == false)
{
oNewArray.add(m_keys.get(i));
}
}
m_keys = oNewArray;
}
return super.remove(key);
}
}
/**
* Returns a collection view of the values contained in this map. The
* collection is backed by the map, so changes to the map are reflected in
* the collection, and vice-versa. The collection supports element
* removal, which removes the corresponding mapping from this map, via the
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a collection view of the values contained in this map.
*/
/*public Collection values()
{
}*/
/**
* Returns a collection view of the mappings contained in this map. Each
* element in the returned collection is a <tt>Map.Entry</tt>. The
* collection is backed by the map, so changes to the map are reflected in
* the collection, and vice-versa. The collection supports element
* removal, which removes the corresponding mapping from the map, via the
* <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
* <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
* It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
*
* @return a collection view of the mappings contained in this map.
* @see Map.Entry
*/
public Set entrySet()
{
return super.entrySet();
}
/**
* Removes all mappings from this map.
*/
public void clear()
{
synchronized(this)
{
m_keys.clear();
super.clear();
}
}
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for this key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
* @return previous value associated with specified key, or <tt>null</tt>
* if there was no mapping for key. A <tt>null</tt> return can
* also indicate that the HashMap previously associated
* <tt>null</tt> with the specified key.
*/
public Object put(Object key, Object value)
{
int iExistingIndex = this.getKeyIndex(key);
Object oldObj = super.put(key, value);
if(iExistingIndex == -1)
{
m_keys.add(key);
}
else
{
m_keys.add(iExistingIndex, key);
}
return oldObj;
}
/**
* Returns a set view of the keys contained in this map. The set is
* backed by the map, so changes to the map are reflected in the set, and
* vice-versa. The set supports element removal, which removes the
* corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
* <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
* <tt>clear</tt> operations. It does not support the <tt>add</tt> or
* <tt>addAll</tt> operations.
*
* @return a set view of the keys contained in this map.
*/
public Set keySet()
{
Set oSet = super.keySet();
final SequentialMap oThis = this;
HashSet oNewSet = new HashSet(oSet){
/**
* Returns an iterator over the elements in this set. The elements
* are returned in no particular order.
*
* @return an Iterator over the elements in this set.
* @see ConcurrentModificationException
*/
public Iterator iterator() {
return new SequentialIterator(oThis);
}
};
return oNewSet;
}
protected int getKeyIndex(Object key)
{
int index = -1;
if(m_keys != null)
{
int iSize = m_keys.size();
for(int i = 0; i < iSize; i++)
{
if(m_keys.get(i).equals(key))
{
index = i;
break;
}
}
}
return index;
}
Object getKey(int index)
{
return m_keys.get(index);
}
}
class SequentialIterator implements Iterator
{
private SequentialMap m_oMap = null;
private int m_iCurrentIndex = 0;
SequentialIterator(SequentialMap oMap)
{
this.m_oMap = oMap;
}
/**
* Returns <tt>true</tt> if the iteration has more elements. (In other
* words, returns <tt>true</tt> if <tt>next</tt> would return an element
* rather than throwing an exception.)
*
* @return <tt>true</tt> if the iterator has more elements.
*/
public boolean hasNext() {
return (m_iCurrentIndex < m_oMap.size());
}
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration.
* @exception NoSuchElementException iteration has no more elements.
*/
public Object next() {
Object key = m_oMap.getKey(m_iCurrentIndex);
m_iCurrentIndex++;
return key;
}
/**
*
* Removes from the underlying collection the last element returned by the
* iterator (optional operation). This method can be called only once per
* call to <tt>next</tt>. The behavior of an iterator is unspecified if
* the underlying collection is modified while the iteration is in
* progress in any way other than by calling this method.
*
* @exception UnsupportedOperationException if the <tt>remove</tt>
* operation is not supported by this Iterator.
* @exception IllegalStateException if the <tt>next</tt> method has not
* yet been called, or the <tt>remove</tt> method has already
* been called after the last call to the <tt>next</tt>
* method.
*/
public void remove() {
Object key = m_oMap.getKey(m_iCurrentIndex - 1);
m_oMap.remove(key);
}
}