我正在使用輪廓掃描儀。對於我想要保存角落/邊緣的每個輪廓。 而不是在輪廓中有一個數組我有一個大的陣列,我分享。原因是它必須在動畫上工作,所以這是爲了優化。如何在這種情況下處理ConcurrentModificationException
這個想法是每個輪廓都是大數組的子列表視圖。
我的工作相當長的一個類,使那麼容易,現在我遇到一個問題:
ArrayList<PVector> vecs = new ArrayList<PVector>();
for (int i = 0; i < 10; i++) {
vecs.add(new PVector());
}
List<PVector> subList = vecs.subList(0, 5);
for (int i = 0; i < 10; i++) {
vecs.add(new PVector());
}
// ConcurrentModificationException
for (int i = 0; i < subList.size(); i++) {
}
首先,它是Java的設計很差,它確實拋出併發修改如果我使用add(Object)
?這應該不會影響我已經擁有的任何子列表,因爲它增加了最後的權利? (邏輯講話)。我的意思是,add(Object)
永遠不會影響已經令人興奮的subList,只有add(index, Object)
可以做到這一點(和其他東西,如刪除,交換和排序)。
二。什麼是解決這個問題的好方法?我可以讓這個大數組真的很大,所以在我已經創建了一個子列表之後,我不太可能需要添加元素,但是我想知道是否還有其他好的方法來處理它。
這是一類我做的,不得不讓我很容易,但讓我的生活困難,現在:)
public class ListDivisor<T> {
List<T> list;
int subListStartIndex = 0;
int currentGetIndex = 0;
InstanceHelper instanceHelper;
public ListDivisor(List<T> list, InstanceHelper<T> instanceHelper) {
this.list = list;
this.instanceHelper = instanceHelper;
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public void reset() {
subListStartIndex = 0;
currentGetIndex = 0;
if (instanceHelper.doResetInstances()) {
for (T obj : list) {
instanceHelper.resetInstance(obj);
}
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public List<T> getSubList(int size) {
int fromIndex = subListStartIndex; // inclusive
int toIndex = fromIndex + size; // exclusive
for (int i = list.size(); i < toIndex; i++) {
list.add((T) instanceHelper.createInstance());
}
subListStartIndex = toIndex;
currentGetIndex = toIndex;
return list.subList(fromIndex, toIndex);
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
/**
* Returns a subList starting where the previous subList ended till
* the latest object added till then.
*
* @return
*/
public List<T> getSubList() {
return getSubList(currentGetIndex-subListStartIndex);
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public T getNext() {
if (currentGetIndex >= list.size()) {
list.add((T)instanceHelper.createInstance());
}
return list.get(currentGetIndex++);
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public void clear() {
list.clear();
reset();
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
public interface InstanceHelper<T> {
public T createInstance();
public boolean doResetInstances();
public void resetInstance(T obj);
}
}
這是如何使用類的一個小例子:
ListDivisor<PVector> vectorsDivisor = new ListDivisor<PVector>(
new ArrayList<PVector>(),
new InstanceHelper<PVector>() {
//@Override
public PVector createInstance() {
return new PVector();
}
//@Override
public boolean doResetInstances() {
return true;
}
//@Override
public void resetInstance(PVector v) {
v.set(0,0,0);
}
});
PVector v = vectorsDivisor.getNext();
v.set(1, 1, 1);
v = vectorsDivisor.getNext();
v.set(2, 2, 2);
v = vectorsDivisor.getNext();
v.set(3, 3, 3);
subList = vectorsDivisor.getSubList();
println("subList size: "+subList.size());
你知道,你可以製作一份子列表的副本,以便修改原件不會導致問題。 – 2014-12-03 03:50:43
那麼,使用listDivisor的'getSubList'返回的子列表會拋出一個ConcurrentModificationException異常嗎? – Edward 2014-12-03 03:52:25
@Edward - 是啊 - 請參閱http://stackoverflow.com/questions/27262602/possible-reason-for-concurrentmodificationexception – 2014-12-03 04:22:48