Good evening,
I am having a weird issue with a method I am trying to implement on Java. I will try and describe it as well as possible:
Basically what it does is checks for the next states an Epsilon-Non Deterministic State Machine would reach, given a state and an array of possible transitions. The method "loadEpsilon(List)" loads up the possible epsilon transitions for the given list of states.
if (transitionList.i开发者_开发百科sEmpty()){
return new HashSet<State>(stateEntryList);
}
else{
for (int i=0; i <= transitionList.size()-1; i++){
for (int j=0; j <= stateEntryList.size()-1; j++){
for (Transition tr : this.transitions()){
if ((tr.fromState() == stateEntryList.get(j)) && (tr.label() == transitionList.get(i))){
if (!stateExitList.contains(tr.toState())){
stateExitList.add(tr.toState());
}
}
}
}
stateEntryList.clear();
stateEntryList = loadEpsilon(stateExitList);
stateExitList.clear();
}
return new HashSet<State>(stateEntryList);
}
So, filling up the whole code with tracing "System.out.print"s right to the very end, just before the
stateExitList.clear();
everything is OK. However, past that line, I print BOTH lists RIGHT after that sentence (StateExitList and StateEntryList) and they are both GONE.
I just can't figure out why they are emptying themselves.
Any chance for help?
Thanks a lot in advanced.
EDIT: This here would be the code for loadEpsilon:
public List<State> loadEpsilon(List<State> states) throws NoInitialStateException{
State stateRead;
if (states.isEmpty()){
if (this.getInitialState() == null){
throw new NoInitialStateException();
}
states.add(this.getInitialState());
return loadEpsilon(states);
}
else{
for (int i=0; i <= states.size()-1;i++){
stateRead = states.get(i);
for (Transition tr : this.transitions()){
if ((tr.fromState() == stateRead) && (tr.label().isEpsilon()) && (!states.contains(tr.toState()))){
states.add(tr.toState());
System.out.print(states.size());
}
}
}
}
return states;
}
The declaration of the lists are the following:
List<State> stateEntryList = new ArrayList<State>();
stateEntryList = loadEpsilon(stateEntryList);
List<State> stateExitList = new ArrayList<State>();
List<Label> listaLabels = new ArrayList<Label>();
listaLabels.addAll(Arrays.asList(labels));
If stateEntryList
is empty after you call stateExitList.clear()
after you call loadEpsilon
, that points toward the List
that loadEpsilon
returns being somehow tied to the stateExitList
being passed to it. Perhaps the list that loadEpsilon
is returning is using the list passed to it as a backing store or something like that? You really need to post the code to loadEpsilon
.
Edited:
Well that explains it. your loadEpsilon
is returning the List
that was passed to it. It is returning the exact same object it was given. So you're ending up with the same object being referred to by two names. But since it's the same object underneath, when you clear it, it's cleared.
You're basically doing this:
List<String> list1 = new ArrayList<String>();
list1.add("foo");
list1.add("bar");
List<String> sameList = list1;
sameList.add("quux");
list1.clear();
Does that make it clearer why clearing one list clears them "both"? (Again, there's only one object there that is being referred to by two reference variables).
Lists do not spontaneously empty themselves in Java. Trust me. It doesn't happen.
This means that there must be a different explanation:
Maybe the two lists are actually the same object, or views on the same object. So clearing one list clears the second one.
Maybe clear is being called on the second list somewhere else, and you haven't spotted it. Or maybe it is happening as a result of remove / removeAll calls.
Maybe the second list was already empty. For instance, where you thought you were adding to the second list you were actually adding to an entirely different list object.
Maybe you are using a custom list implementation that has broken behaviour; e.g. some other operation is effectively deleting things as a mistaken side-effect.
Maybe it is something else ...
We are not going to help you with this without all of the relevant code (with the traceprint code included) and the output from the traceprints.
Is loadEpsilon
using deferred execution? That would explain why emptying the list passed to it would result in the list it returns being empty.
精彩评论