我的代码的问题是,当我在下面调用generateCSV()
时,ArrayList的输出不正确。它只用最后一个要实例化的实例替换所有实例,即最后一个实例正在替换所有先前的实例。
我的基类PausePred
采用字符串和ArrayList
public class PausePred {
private String predString; // the keys preceding the pause
private ArrayList<KSE> kseArr; // the arraylist of KSEs comprising the PausePred
public PausePred(String predStr) {
this.predString = predStr;
kseArr = new ArrayList<KSE>();
}
public void setKseArr(ArrayList<KSE> kseArr) {
this.kseArr.addAll(kseArr);
}
在PausePred
内,我有一个静态方法来创建PausePreds
数组。
public static Collection<PausePred> parseKseArray(KSE[] kArr) {
Collection<PausePred> pausePredArray = new ArrayList<PausePred>();
String pausePredStr = ""; // to store incrementally appended events preceding pause
int pauseDur = 0; // to store pause duration
boolean startPosSet = false; // checks if startPos has been set
ArrayList<KSE> pausePredKseArr = new ArrayList<KSE>();;
for (int kseArrIdx = 0; kseArrIdx < kArr.length; kseArrIdx++) {
if (kArr[kseArrIdx].isKeyPress()) { // only down-keys
// if start positio"n has not been set, set it, and update flag
// set time stamp, as well
if (startPosSet == false) {
startPosSet = true;
// get first char of PredStr by going back one index
if (kseArrIdx > 0) {
pausePredStr = VisualCharStream.vkCodetoString(kArr[kseArrIdx-1].getKeyCode());
pausePredKseArr.add(kArr[kseArrIdx-1]);
}
}
if (kArr[kseArrIdx].getM_pauseMs() < PauseBursts.PAUSE) { // is not a pause
//append vkCode (to string) to pausePred
pausePredStr += VisualCharStream.vkCodetoString(kArr[kseArrIdx].getKeyCode());
pausePredKseArr.add(kArr[kseArrIdx]);
}
else { // is a pause
//start incrementing pause duration, until a non-pause is reached
while (kArr[kseArrIdx].getM_pauseMs() >= PauseBursts.PAUSE) {
pauseDur = (int) kArr[kseArrIdx].getM_pauseMs();
kseArrIdx++;
}
//add to pausePred array
PausePred pp = new PausePred(pausePredStr);
pp.setKseArr(pausePredKseArr);
pausePredArray.add(pp);
//reset variables
pausePredStr = "";
startPosSet = false;
pausePredKseArr.clear();
//need to take one step back from above while loop
kseArrIdx--;
}
} // close outer if loop
} // close for loop
return pausePredArray;
} // close parseKseArray()
当我在下面调用这个方法时,第一部分给出了每个实例,但第二部分只给出了数组中最后一个实例的kseArr。
public static void generateCSV(String fileName,ArrayList<PausePred> pausePredArr) {
for (PausePred pp : pausePredArr)
System.out.println(pp.getPredString()+"\t"+pp.kseArr.get(pp.kseArr.size()-1).getKeyCode());
}
这是调用上面的解析方法的提取方法。我不确定它是否与这个问题密切相关。
public class ExtractPausePred implements ExtractionModule {
private static ArrayList<PausePred> pausePredArray = new ArrayList<PausePred>();
@Override
public void extract(DataNode data) {
for (Answer a : data) {
//create KSE array
KSE[] kseArr = parseSessionToKSE(a.getKeyStrokes());
//from above KSE array, extract Pause Predecessors
pausePredArray.addAll(PausePred.parseKseArray(kseArr));
PausePred.generateCSV("testing123",pausePredArray);
}
return null;
}
}
答案 0 :(得分:1)
问题是您尝试通过重复使用相同的对象来提前优化:
pausePredKseArr.clear();
创建一个新的ArrayList
而不是清除旧的{{1}},你就可以了。
答案 1 :(得分:-1)
我的代码的问题是,当我调用下面的generateCSV()时,ArrayList的输出不正确。它只用最后一个要实例化的实例替换所有实例,即最后一个实例正在替换所有先前的实例。
我没有详细阅读您的代码,也许您可以尝试减少它。但
这几乎总是因为相同的对象(修改后)被添加到集合中,而不是每次都创建new
实例:
SomeType s = new SomeType();
while (condition) {
s.setAttr1(value1);
s.setAttr2(value2);
collection.add(s);
}
你拥有的是s
中每个索引的collection
对象。它的属性将在上一次迭代中添加相同的值。
您需要的是:
while (condition) {
SomeType s = new SomeType();
s.setAttr1(value1);
s.setAttr2(value2);
collection.add(s);
}
通过在循环内创建对象,每次迭代都会添加一个不同的对象。