ArrayList丢失了我的引用

时间:2015-04-26 03:15:13

标签: java oop object arraylist synchronization

我的主驱动程序类中有一个静态ArrayList(masterLog)。 ArrayList包含Event对象,Event对象具有ArrayList (heats)作为全局变量。将热对象作为ArrayList (racers)作为全局变量。现在,当我有以下代码行时:

  

的System.out.println(ChronoTimer1009System.getMasterLog()得到(0).getHeats()得到(getCurHeat())getRacers()的toString()。);

这会返回[],即使getRacers()不是空的!

当我这样称呼时:

System.out.println(getHeats().get(getCurHeat()).getRacers());

这将返回正确的填充数组。

我想我需要同步masterLog ArrayList,但我不确定如何。我尝试过同样的方式,就像Stack Exchange上的其他线程推荐的那样,但没有运气。

似乎静态ArrayList masterLog更新了两个级别,但如果有意义则不会更新三个级别。

我做错了什么?

更新:

也许这有助于解释:

在我的main(驱动程序)类中,我有一个名为masterLog的静态ArrayList。此ArrayLIst的目的是存储Event对象的实例以供以后的数据检索。现在,在不太复杂的情况下,Event类包含一个名为heats的ArrayList,而Heat类包含一个名为racers的ArrayList。当我在程序中的某个点访问masterLog ArrayList时(当其他ArrayLists填充数据时),例如通过调用“masterLog.getHeats()。get(0).getRacers()”,masterLog不会在racers ArrayList中查找任何数据。但是,它确实在加热ArrayList中找到数据。换句话说,存储在masterLog中的对象实例仅将信息更新为2的深度(如果有意义则不是3)。

更新:

以下是一些代码:

ChronoTimer1009System类(驱动程序)

package main;

import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;

public class ChronoTimer1009System {

private Event curEvent;
private static Channel[] channels = new Channel[8];
private boolean state;
private static Stack<Log> log;
private  static ArrayList<Event> masterLog;
private static Printer p;
public static Time globalTime;
private int oldLogSize; //used only in this.export()

public ChronoTimer1009System() throws UserErrorException{
    for(int i=0; i<channels.length; ++i){channels[i] = new Channel(SensorType.NONE);}  // initialize channels
    masterLog = new ArrayList<Event>(); //this holds references to each event
    this.newEvent(EventType.IND);
    this.state = false; //system is initally off
    log = new Stack<Log>();
    p = new Printer();
    globalTime = null;
    oldLogSize = 0;
}

public void newEvent(EventType e) throws UserErrorException {
    switch(e){
        case IND: this.curEvent = new IND();ChronoTimer1009System.masterLog.add(this.curEvent);break;
        case PARIND: this.curEvent = new PARIND();ChronoTimer1009System.masterLog.add(this.curEvent);break;
        case GRP: this.curEvent = new GRP();ChronoTimer1009System.masterLog.add(this.curEvent);break;
        case PARGRP: this.curEvent = new PARGRP();ChronoTimer1009System.masterLog.add(this.curEvent);break;
    }
    for(Channel x : channels){if(x.getState()) x.toggleState();}
}

public void on() throws UserErrorException{
    if(state) throw new IllegalStateException();
    this.curEvent = new IND();
    ChronoTimer1009System.globalTime = new Time(0);
    state = true;
}

public void reset() throws UserErrorException{
    if(state) state = false;
    on();
}

public void exit(){
    this.curEvent = null;
    ChronoTimer1009System.globalTime = null;
    if(!state) throw new IllegalStateException();
    state = false;
}

public static Time searchElapsedByID(int idNum){
    Time toReturn = null;
    for(Log item : log){
        if(item.getCompetitorNumber() == idNum){
            toReturn = item.getElapsedTime(); break;
        }
    }
    return toReturn;
}

/**
 * @return the curEvent
 */
public Event getCurEvent() {
    return curEvent;
}

/**
 * @return the state
 */
public boolean isState() {
    return state;
}

public static Channel getChan(int chan){
    if(chan < 1 || chan > 8) throw new IllegalArgumentException("Argument is not in range");
    return channels[chan-1];
}

public static void export(){
    //*****FORMAT JSON*****
    //before formating, a sort of the runners within each heat is needed to determine place.
    String toJson = "{\"events\":[";
    System.out.println(ChronoTimer1009System.getMasterLog().get(0).getHeats().get(0).getRacers().size());
    //iterate through each event
    for(int i = 0; i < ChronoTimer1009System.getMasterLog().size(); ++i){
        //iterate through each heat of each event
        toJson += "{\"name\":\"" + ChronoTimer1009System.getMasterLog().get(i).getType().toString() + "\",\"heats\":[";
        for(int j = 0; j < ChronoTimer1009System.getMasterLog().get(i).getHeats().size(); ++j){
            //iterate through each competitor in each heat
            toJson += "{\"runners\":[";
            System.out.println(ChronoTimer1009System.getMasterLog().get(i).getHeats().size());
            ArrayList<Competitor> x = sortByPlace(ChronoTimer1009System.getMasterLog().get(i).getHeats().get(j).getRacers()); <----- on this line, the getRacers() part has a size of zero when it isn't empty.
            for(int k = 0; k < x.size(); ++k){
                //notice we are working with a sorted copy
                //TODO make Competitor endTime the elapsed time
                toJson += "{\"place\":\"" + String.valueOf(k+1) + "\",\"compNum\":\"" + x.get(k).getIdNum() + "\", \"elapsed\":\"" + x.get(k).getEndTime().toString() + "\"},";
            }
            toJson += "]},";
        }
        toJson += "]},";
    }

    toJson += "}";

    System.out.println(toJson);

    /*try{
        URL site = new URL("http://7-dot-eastern-cosmos-92417.appspot.com/chronoserver");
        HttpURLConnection conn = (HttpURLConnection) site.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());

        String data = "data=" + toJson;
        out.writeBytes(data);
        out.flush();
        out.close();
        System.out.println("Done sent to server");

        new InputStreamReader(conn.getInputStream());
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }*/
}

private static ArrayList<Competitor> sortByPlace(ArrayList<Competitor> unsorted)
{
    ArrayList<Competitor> whole = (ArrayList<Competitor>) unsorted.clone();

    ArrayList<Competitor> left = new ArrayList<Competitor>();
    ArrayList<Competitor> right = new ArrayList<Competitor>();
    int center;

    if(whole.size()==1)    
        return whole;
    else
    {
        center = whole.size()/2;
        // copy the left half of whole into the left.
        for(int i=0; i<center; i++)
        {
                left.add(whole.get(i));
        }

        //copy the right half of whole into the new arraylist.
        for(int i=center; i<whole.size(); i++)
        {
                right.add(whole.get(i));
        }

        // Sort the left and right halves of the arraylist.
        left  = sortByPlace(left);
        right = sortByPlace(right);


        // Merge the results back together.
        merge(left,right,whole);

    }
    return whole;
}

private static void merge(ArrayList<Competitor> left, ArrayList<Competitor> right, ArrayList<Competitor> whole) {

    int leftIndex = 0;
    int rightIndex = 0;
    int wholeIndex = 0;


    // As long as neither the left nor the right arraylist has
    // been used up, keep taking the smaller of left.get(leftIndex)
    // or right.get(rightIndex) and adding it at both.get(bothIndex).
    while (leftIndex < left.size() && rightIndex < right.size())
    {
        if ((left.get(leftIndex).getEndTime().compareTo(right.get(rightIndex)))<0) 
        {
            whole.set(wholeIndex,left.get(leftIndex));
            leftIndex++;
        }
        else
        {
            whole.set(wholeIndex, right.get(rightIndex));
            rightIndex++;
        }
        wholeIndex++;
    }

    ArrayList<Competitor>rest;
    int restIndex;
    if (leftIndex >= left.size()) {
        // The left arraylist has been use up...
        rest = right;
        restIndex = rightIndex;
    }
    else {
        // The right arraylist has been used up...
        rest = left;
        restIndex = leftIndex;
    }

    // Copy the rest of whichever arraylist (left or right) was
    // not used up.
    for (int i=restIndex; i<rest.size(); i++) {
        whole.set(wholeIndex, rest.get(i));
        wholeIndex++;
    }
}

/**
 * @return the log
 */
public static Stack<Log> getLog() {
    return log;
}

/**
 * @return the masterLog
 */
public static ArrayList<Event> getMasterLog() {
    return masterLog;
}

/**
 * @return the p
 */
public static Printer getPrinter() {
    return p;
}
}

活动类:

package main;
import java.util.ArrayList;

public abstract class Event extends Display{

private ArrayList<Heat> heats;
private int curHeat; //private means only this class can modify, not the subclasses
private Competitor curComp;
private String name;

public Event(String name) throws UserErrorException{
    this.name = name;
    heats = new ArrayList<Heat>();
    curHeat = -1;
    curComp = null;
    createRun();
}

/**
 * This method will be used by all EventTypes and will not change
 * regardless of the EventType.
 * @throws UserErrorException
 */
public void createRun() throws UserErrorException{
    heats.add(new Heat()); ++curHeat;
}

/**
 * @return the heats
 */
public ArrayList<Heat> getHeats() {
    return heats;
}

/**
 * @return the name
 */
public String getName() {
    return name;
}

/**
 * @return the currentHeat
 */
public int getCurHeat() {
    return curHeat;
}

/**
 * @return the curComp
 */
public Competitor getCurComp() {
    return curComp;
}

/**
 * @param curComp the curComp to set
 */
public void setCurComp(Competitor curComp) {
    this.curComp = curComp;
}

/* (non-Javadoc)
 * @see Display#displayHeatNumber()
 */
@Override
public String displayHeatNumber() {
    // TODO Auto-generated method stub
    return "Heat: " + (curHeat+1);
}

/* (non-Javadoc)
 * @see Display#displayFinished()
 */
@Override
public String displayFinished() {
    String toReturn = "";
    boolean noRunners = true;
    for(Competitor x : getHeats().get(getCurHeat()).getRacers()){
        if(x.getEndTime() != null){
            toReturn += "\n" + x.getIdNum() + " " + (ChronoTimer1009System.searchElapsedByID(x.getIdNum()).equals(new Time(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE)) ? "DNF" : ChronoTimer1009System.searchElapsedByID(x.getIdNum()).toString() + " F");
            noRunners = false;
        }
    }
    if(noRunners){toReturn = "no runners have finished";}
    return toReturn;
}

public abstract void endRun() throws UserErrorException;

public abstract void trigChan(int chan, boolean dnf) throws UserErrorException;

public abstract void cancel(int ln) throws UserErrorException;

public abstract EventType getType();
}

热火课程:

package main;
import java.util.ArrayList;

public class Heat {

private ArrayList<Competitor> racers;
//private ArrayList<Competitor> racers;
private int currentCompetitor;

/**
 * Constructor
 */
public Heat(){
    racers = new ArrayList<Competitor>();
    //racers = new ArrayList<Competitor>();
    currentCompetitor = 0;
}
/**
 * Set selected racer as next on to start
 * @param racer the racer to start next
 */
public void setNextCompetitor(Competitor x){
    int pos = racers.indexOf(x);
    if(pos == -1 || pos<currentCompetitor) throw new IllegalArgumentException("Competitor not in the race! Please add first");
    for(int i = pos; i>currentCompetitor; --i){
        racers.set(i, racers.get(i-1));
    }
    racers.set(currentCompetitor, x);

}
/**
 * Take the selected runner (the next runner) out from the race
 * @param racer the runner to be cleared
 */
public void clearNextCompetitor() throws UserErrorException {
    if(racers.size()-(currentCompetitor)<1) throw new UserErrorException("No runners to clear!");
    for(int i = currentCompetitor+1; i<racers.size(); ++i){
        racers.set(i-1, racers.get(i));
    }
    racers.remove(racers.size()-1);
}
/**
 * basically a remove method
 * @param x
 */
public void remove(Competitor x){
    int pos = racers.indexOf(x);
    if(pos < 0) throw new IllegalArgumentException("runner does not exists");
    racers.remove(pos);
}

/**
 * Swaps two runners positions in line
 */
public void swap() throws UserErrorException{
    int count = 0;
    for(Competitor x : racers){
        if(x.getStartTime() == null) ++count;
    }
    if(count > 1 && currentCompetitor + 1 <= racers.size()){
        Competitor first = racers.get(currentCompetitor);
        Competitor second = racers.get(currentCompetitor+1);
        racers.set(currentCompetitor, second);
        racers.set(currentCompetitor+1, first);
    }
    else{
        throw new UserErrorException("Not enough competitors to swap");
    }
}
/**
 * Add a competitor to the end of the current line of competitors if any
 * @param x the competitor to add
 */
public boolean addCompetitor(Competitor x) throws UserErrorException{
    if(x.getIdNum() < 0 || x.getIdNum() > 99999) throw new UserErrorException("ID number out of range");
    if(x.getRunNum() < 0) throw new IllegalArgumentException("Run Num Out of range");
    boolean add = true;
    for(Competitor i : racers){
        if(i.getIdNum() == x.getIdNum()){
            add = false;
            break;
        }
    }
    if(add){
        racers.add(x);  
    }
    return add;
}
/**
 * Retrieve the next competitor if there is one
 * @return the next competitor
 */
public Competitor getNextCompetitor() throws UserErrorException{
    if(!hasNextCompetitor()) throw new UserErrorException("There are no more competitors!");
    while(racers.get(currentCompetitor).isCompeting()){++currentCompetitor;}
    return racers.get(currentCompetitor++);
}
/**
 * used to fix the order of the queue after cancel is called
 */
public void fix(EventType x){
    switch(x){
    case IND: 
        --currentCompetitor;
    break;

    case GRP: case PARGRP: case PARIND:
        for(int i = 0; i<racers.size(); ++i){
            if(racers.get(i).getStartTime() == null){
                currentCompetitor = i;
                break;
            }
        }
    break;
    }
}
/**
 * Is there another competitor to go?
 * @return whether or not there is another competitor to go.
 */
public boolean hasNextCompetitor(){
    return currentCompetitor < racers.size();
}
/**
 * Return a 1D array view of the competitors
 * @return
 */
public ArrayList<Competitor> getRacers(){
    return racers;
}
}

在ChronoTimer1009System类的导出方法中,我指出错误在哪里以及发生了什么

0 个答案:

没有答案