通过引用vs值java

时间:2012-12-04 02:40:20

标签: java reference state

我正在尝试解决着名的8拼图,其中一个3 * 3的正方形填充了1个空插槽和8个数字,解决方法是将其恢复到原始状态。

要做到这一点,我有一个arraylist的“状态”,存储数字0~9,代表拼图。

解决方案涉及产生大量可能的移动状态,这意味着我保存了所做出的每一个合法行动以及由此产生的难题。这是使用以下方法完成的,但我的swapAndStore不会在每次传递时编辑原始传递的数组。相反,当在下面的genSuccessors()中调用时,它将在第一个if条件下正常工作,然后在第一个if的结果上应用下一个if条件。我认为我通过创建一个名为“oldBoard”的新拼图状态来修复问题,以保存原始输入拼图以供将来参考,但这也无效。一位朋友告诉我,这可能与参考问题有关,我无法很好地掌握。据我所知,当x = 0,y = 1时,java不会进行交换(x,y),因此x = 1,y = 0,但是在这里看不到这是怎么回事。 建议?

   private void swapAndStore(int d1, int d2, ArrayList<State> s)
{
    //int[] cpy = copyBoard(curBoard);
    int[] cpy = new int [curBoard.length];
    System.arraycopy(curBoard,0,cpy,0,curBoard.length);
    int[] oldBoard = new int [curBoard.length];
    System.arraycopy(curBoard,0,oldBoard,0,curBoard.length);
    int temp = cpy[d1];
    cpy[d1] = cpy[d2];
    cpy[d2] = temp;
    s.add((new State(cpy)));
    curBoard = oldBoard;
    System.out.println("swapandstore storing" );
    s.get(s.size()-1).printState();

}

public ArrayList<State> genSuccessors()
{
    ArrayList<State> successors = new ArrayList<State>();
    int hole = getHole();

    // try to generate a state by sliding a tile leftwise into the hole
    // if we CAN slide into the hole
    if (hole != 0 && hole != 3 && hole != 6)
    {
        /*
         * we can slide leftwise into the hole, so generate a new state for
         * this condition and throw it into successors
         */;
        System.out.println("left");
        swapAndStore(hole - 1, hole, successors);
    }

    // try to generate a state by sliding a tile topwise into the hole
    if (hole != 6 && hole != 7 && hole != 8)
    {
        System.out.println("top");
        swapAndStore(hole + 3, hole, successors);
    }

1 个答案:

答案 0 :(得分:1)

Java是按值传递的 - 总是

基元按值传递;对象引用按值传递。

这意味着您无法更改引用的值。但是对于对象,你可以改变它们的状态 - 如果它们是可变的。

所以你可以这样做:

package cruft;

import java.io.PrintStream;

/**
 * ArraySwapDemo description here
 * @author Michael
 * @link
 * @since 12/3/12 9:48 PM
 */
public class ArraySwapDemo {

    public static void main(String[] args) {
        System.out.println(String.format("before: %s", arrayToString(args)));
        swapValues(args, 0, args.length-1);
        System.out.println(String.format("after : %s", arrayToString(args)));
    }

    // No checks for proper indexes, but you get the idea.
    private static void swapValues(String[] args, int i, int j) {
        String temp = args[i];
        args[i] = args[j];
        args[j] = temp;
    }

    public static String arrayToString(String [] array) {
        StringBuffer buffer = new StringBuffer(1024);
        buffer.append('{');
        for (int i = 0; i < array.length-1; ++i) {
           buffer.append(array[i]).append(',');
        }
        buffer.append(array[array.length-1]).append('}');
        return buffer.toString();
    }

}

如果我在命令行上使用四个字符串运行它 - foo bar baz bat - 我得到了这个结果:

java cruft.ArraySwapDemo foo bar baz bat
before: {foo,bar,baz,bat}
after : {bat,bar,baz,foo}

Process finished with exit code 0