我需要一些帮助来理解这里发生的事情。我在向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的dev设置中运行时工作正常但在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);
}
}
答案 0 :(得分:1)
我猜你的Weblogic正在使用旧版本的JRockit。我已经检查了最后一个版本的the source code,他们不再使用这个buildCache了。
我不确定,但我认为如果你更换它:
public boolean hasNext() {
return (m_iCurrentIndex < m_oMap.size());
}
用于此实现:
public boolean hasNext() {
return (m_iCurrentIndex < m_keys.size());
}
你不会有这个错误。
如果没有下一个元素,你还需要在next()方法上抛出NoSuchElementException
,而不是抛出当前实现正在做的IndexOutOfBoundsException
。
添加类似这样的内容
if (!hasNext()) {
throw new NoSuchElementException();
}