问题
I'm getting an error where it would keep giving me a stack overflow. What I basically wanna do is create an Array List of objects that have rectangles. However, if any of the object overlap one another then, I would call the method again and create an array till it creates an array of objects that do not overlap. Can anyone tell me whats wrong?
public class TokenArrayCreator {
public final int TOKEN_WIDTH= 35;
private GameToken token1;
private ArrayList<GameToken> tokenarr;
public TokenArrayCreator()
{}
public ArrayList<GameToken> ArrayCreator()
{
ArrayList<GameToken> tokenArray = new ArrayList<GameToken>();
Random random = new Random();
for(int i =0; i<=10 ;i++)
{
GameToken token= new GameToken(random.nextInt(300),random.nextInt(300),35,35);
tokenArray.add(token);
}
for(int i =0 ; i<=10 ; i++) // make two list i and j && if i != j
{
for(int j= 0; j<=10 ; j++)
{
if(i!=j)
{
if(tokenArray.get(i).overlaps(tokenArray.get(j)))
{
TokenArrayCreator t1= new TokenArrayCreator();
t1.ArrayCreator();
}
}
else break;
}
}
return tokenArray;
}
Above is my array creator class. Below is my overlap method that is in another class.
public boolean overlaps(VisibleShape other)
{
GameToken other1 = (GameToken) other;
if(this.bbox.intersects(other1.bbox))
{
return true;
}
else return false;
}
Here is the stack trace
Exception in thread "main" java.lang.StackOverflowError
at java.util.Hashtable.hash(Unknown Source)
at java.util.Hashtable.get(Unknown Source)
at javax.swing.UIDefaults.getFromHashtable(Unknown Source)
at javax.swing.UIDefaults.get(Unknown Source)
at javax.swing.MultiUIDefaults.get(Unknown Source)
at javax.swing.UIDefaults.getFont(Unknown Source)
at javax.swing.UIManager.getFont(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at CircPattern.<init>(CircPattern.java:25)
at Pattern.<init>(Pattern.java:40)
at GameToken.<init>(GameToken.java:18)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:26)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
at TokenArrayCreator.ArrayCreator(TokenArrayCreator.java:40)
回答1:
Basically, what you are doing, each time you find two intersecting objects, you are creating a brand new instance of TokenArrayCreator
and then call it's ArrayCreator
method.
This creates a brand new ArrayList
and attempts to fill it again, when it finds intersecting objects, it creates a brand new instance of TokenArrayCreator
and calls it's ArrayCreator
....over and over again...
Apart from the fact that none of these instance have any relationship to each other (none of them knows what the other have created), it's very rare that any one would be able to create a full array of non-overlapping objects, hence your problem.
Instead, consider removing one of the offending objects from the ArrayList
and continue trying to create objects until it reaches it's desired size, for example...
public class TokenArrayCreator {
public final int TOKEN_WIDTH = 35;
private ArrayList<Rectangle> tokenarr;
public TokenArrayCreator() {
}
public void ArrayCreator() {
tokenarr = new ArrayList<Rectangle>();
Random random = new Random();
int requiredObjectCount = 11;
while (tokenarr.size() < requiredObjectCount) {
for (int i = 0; i < requiredObjectCount - tokenarr.size(); i++) {
Rectangle token = new Rectangle(random.nextInt(300), random.nextInt(300), 35, 35);
tokenarr.add(token);
}
for (int i = 0; i < tokenarr.size(); i++) // make two list i and j && if i != j
{
for (int j = 0; j < tokenarr.size(); j++) {
if (i != j) {
if (tokenarr.get(i).intersects(tokenarr.get(j))) {
tokenarr.remove(j);
}
}
}
}
}
}
public ArrayList<Rectangle> getList() {
return tokenarr;
}
}
Now, from my persepective, this probably isn't the "fastest" solution, in that you will need to loop multiple times to get the ArrayList
to fill properly and the it's not time consistent (each time you run it, it will take a different time to run) and there is a very small chance that it will never return (depending on the available size and the number of objects you create), but it will solve your immeditate problem
来源:https://stackoverflow.com/questions/29022688/array-creation-stack-overflow