线程“main”中的异常java.lang.IndexOutOfBoundsException:索引:0,大小:0

时间:2015-03-22 07:29:59

标签: java arraylist

我正在尝试编写一个可以解决8-Puzzle问题的程序。我正在使用A *算法来找到解决方案。 我已多次查看我的代码,并尝试进行一些更改。 甚至我的朋友都试图帮助我找到这个错误,但他们无法做到。我仍然不明白我哪里出错了。我使用javadocs看看我做错了什么,即使是解决我的问题。我创建了三个类来解决这个问题。

import java.util.*;
public class Solver implements Iterable<State>
{
    ArrayList<State> queue,solQueue;
    public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
    int temp[][],i;
    int moves;
    int leastPriority,removeIndex;
    State removeTemp;
    public Solver(State initial)
    {
        queue = new ArrayList<State>();
        solQueue = new ArrayList<State>();
        queue.ensureCapacity(16);
        solQueue.ensureCapacity(16);
        temp = new int[3][3];
    i=1;
    leastPriority = 100;
    removeTemp=initial;
    queue.add(removeTemp);
    Iterator<State> qu = queue.iterator();
    while(removeTemp.m!=sol)
    {
        leastPriority = 100;
        i=0;
        queue.iterator();
        for (State s : queue) 
        {
            if((s.mh + s.count) <leastPriority)
            {
                leastPriority = (s.mh + s.count);
                removeIndex = i;
            }
            if(qu.hasNext())
                i++;
        }
        for(State s : removeTemp.neighbours() )
        {
            queue.add(s);
        }
        removeTemp=queue.remove(removeIndex);
        solQueue.add(removeTemp);
    }
    this.moves();
    this.solution();
}
public int moves() 
{
    System.out.print("Solution found out in "+ moves+" moves");
    moves = removeTemp.count;
    return moves;
}
public Iterable<State> solution() 
{
    for(State s : solQueue)
    {
        System.out.println(s.m);
        System.out.println("");
    }
    return solQueue;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Iterator iterator() {
    return null;
}
}

JVM正在抛出异常。

     Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:  0,Size: 0
     at java.util.ArrayList.rangeCheck(Unknown Source)
     at java.util.ArrayList.get(Unknown Source)
     at Solver.<init>(Solver.java:41)
     at Main.main(Main.java:13)

我不明白的是,当我明确地将其声明为16时,ArrayList的大小如何为1。

State Class具有启发式功能,可以使算法有效。以下是State Class。

  import java.util.ArrayList;
  import java.util.Iterator;

  public class State implements Iterable<State>
  {
   public int sol[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 0 } };
   int m[][], bi, bj, count, priority, si, sj;
   int i,j,tempm[][];
   int mh = 0;
   boolean isInitialState, isRepeatedState;
   State previousState, tempState;
   ArrayList<State> neighbourStates;

   public State(State s, int c, int[][] array) 
{
    neighbourStates = new ArrayList<State>();
    neighbourStates.ensureCapacity(16);

    tempState =this;
    m = new int[3][3];
    m=array;

    if (s == null) 
    {
        isInitialState = true;
        count = 0;
        previousState =null;
    } 
    else 
    {
        previousState = s;
        count = c+1;
    }

    this.findZero();
    this.manhattanHeuristic();
}

private void findZero() 
{
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
        {
            if(m[i][j]==0)
            {
                bi=i;
                bj=j;
            }
        }
}

private void manhattanHeuristic() {
    int n = 1;
    mh = 0;
    for (int i = 0; i < 3; i++)
        Z: for (int j = 0; j < 3; j++) {
            if ((i == bi) && (j == bj)) {
                continue Z;
            }

            else if (m[i][j] == n) {
                n++;
            }

            else {
                this.getSolutionIndex();
                mh = mh + Math.abs(i - si) + Math.abs(j - sj);
            }

        }
}

void getSolutionIndex() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++) {
            if (m[i][j] == 0) {
                si = i;
                sj = j;
            }
        }

}

public Iterable<State> neighbours()
{
    tempm = m;
    this.up();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.down();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.left();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    this.right();
    if(!(equals(tempm)))
    {
        tempState = new State(this,count,tempm);
        neighbourStates.add(tempState);
    }

    return neighbourStates;     

}

public boolean equals(int s[][])
{
    if((isInitialState==false)&&(previousState.m == s))
        return true;
    else
        return false;

}

@Override
public Iterator<State> iterator() {
    // TODO Auto-generated method stub
    return null;
}

public void up()
{
    if ((bi > 1) && (bi < 2) && (bj < 3)&& (bj > 1))
    {
        i = bi;
        i = i + 1;
        this.move(i,bj);
    }

}

public void  down()
{
    if ((bi > 2) && (bi < 3) && (bj < 3) && (bj > 1)) 
    {
        i = bi;
        i = i - 1;
        this.move(i,bj);
    }
}

public void left()
{
    if ((bi > 1) && (bi < 3) && (bj < 2)&& (bj > 1)) {
        j = bj;
        j = j + 1;
        this.move(bi, j);
    }
}

public void right()
{
    if ((bi > 1) && (bi < 3) && (bj < 3) && (bj > 2)) {
        j = bj;
        j = j - 1;
        this.move(bi, j);

    }

}

public void move(int x, int y) {
    {
        tempm = m;
    }
    if ((tempm[x + 1][y] == 0) || (tempm[x - 1][y] == 0) || (tempm[x][y + 1] == 0)|| (tempm[x][y - 1] == 0)) {
        tempm[bi][bj] = tempm[x][y];
        tempm[x][y] = 0;
        bi = x;
        bj = y;



    }
}

}

最后是具有主要功能的类。

  import java.util.Scanner;
  public class Main {
  public static void main(String[] args) 
  {
     @SuppressWarnings("resource")
     Scanner sc = new Scanner(System.in);
     int[][] tiles = new int[3][3];
     System.out.println("Enter the elements");
     for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            tiles[i][j] = sc.nextInt();
     State initial = new State(null,0,tiles);
     Solver solver = new Solver(initial);
     solver.solution();

     System.out.println("Minimum number of moves = " + solver.moves());

     }

}

3 个答案:

答案 0 :(得分:4)

  

我不明白的是当我明确地将其声明为16时,ArrayList的大小如何为1。

您没有将ArrayList的大小设置为16.您已设置容量:

queue.ensureCapacity(16);
solQueue.ensureCapacity(16);

这不会使ArrayList的大小为16。

ArrayList有一个数组来保存其数据。当您向ArrayList添加更多元素并且其内部数组已满时,它将必须分配更大的数组并复制其当前持有的内容以及新元素。

ArrayList容量是内部数组的最小大小。您可以使用ensureCapacity确保ArrayList不必经常调整大小(调整内容和复制内容是一项昂贵的操作)。因此,ensureCapacity是您为使其有效工作而进行的一次电话会议。

它不会使ArrayList有16个元素;它只确保ArrayList有至少16个元素的空间。

如果您希望ArrayList包含16个元素,则必须逐个添加这些元素。

答案 1 :(得分:1)

集合的大小和容量是两个不同的概念。

  • capacity表示集合在没有重新分配的情况下可以容纳的项目的最大大小。
  • size表示集合中的当前项目数。

IndexOutOfBoundsException表示您正在尝试访问具有该集合中不存在的索引的项目。

答案 2 :(得分:0)

请在Solver.java中尝试以下代码

如果(!queue.isEmpty())     removeTemp = queue.remove(removeIndex); 其他     打破;