【问题标题】:Java ArrayList of Arrays contains returns unexpected resultJava ArrayList of Arrays 包含返回意外结果
【发布时间】:2016-09-22 00:55:09
【问题描述】:

我正在为计算机和用户之间的井字游戏编写代码。为了进行移动,提供了棋盘上未占用的位置列表作为参数,对于用户而言,这实际上仅用于比较输入是否在列表中。如果是这样,那就构成了合法的举动。

这是我的代码。它一直说新的举动不包含在列表中,我不知道为什么。我在这里的数据库中搜索了一个类似的问题,发现了一些相关但不是结论性的问题。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class UserTTTPlayer implements TicTacToePlayer{

@Override
public int[] makeMove(ArrayList<int []> unusedMoves) {

    Scanner in = new Scanner (System.in);
    System.out.println("Your move, user?");
    String input = in.nextLine();
    int [] move = checkInput(input, unusedMoves);
    while (move == null){
        input = in.nextLine();
        move = checkInput(input, unusedMoves);
    }

    return move;
}

private int [] checkInput(String input, ArrayList<int []> unusedMoves){

    System.out.println("Unused moves: ");
    for (int [] move: unusedMoves)
        System.out.println(Arrays.toString(move));

    //error checking for the length of the input
    if (input.length() < 1 || input.length() > 2){
        System.out.println("Invalid input. Please try again.");
        return null;
    }
    else{

        //convert the input from string to int
        int col = input.charAt(0) - 'a';
        int row = input.charAt(1) - '0';
        int [] move = {row, col};
        System.out.println("Intended move: " + Arrays.toString(move));
        System.out.println(unusedMoves.contains(move));

        //error checking for the bounds of the board
        if (col > 3 || col < 0 || row > 3 || col < 0){
            System.out.println("Invalid input.");
            return null;
        }

        //error checking for if the space is available
        else if (!unusedMoves.contains(move)){
            System.out.println("That space is already occupied.");
            return null;
        }
        return move;
    }
}
}

这是它的输出。板子和其他印刷品来自不同的班级,但我认为与问题无关。我打印出列表,上面说它有新的移动,但包含仍然返回 false。

You go first. You will be X's.
  a b c
0 - - - 
1 - - - 
2 - - - 

Your move, user?
a0
Unused moves: 
[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
[2, 0]
[2, 1]
[2, 2]
Intended move: [0, 0]
false
That space is already occupied.

任何帮助将不胜感激。

【问题讨论】:

  • Array 没有实现 equals 方法,在 list 中用于 contains 方法
  • 您比较col 三次:col &gt; 3 || col &lt; 0 || row &gt; 3 || col &lt; 0。刚发现。
  • !unusedMoves.contains(move) ,此代码不起作用,因为您正在比较数组对象,这不会给出正确的结果。您需要检查数组元素,例如unusedMoves.get(0)[0]==move[0] &amp;&amp; unusedMoves.get(0)[1]==move[1]。你可能需要一个循环来遍历unusedMoves 列表
  • @Amit.rk3 一个不那么冗长的方法是调用Arrays.equals(unusedMoves.get(0), move)。仍然需要像你说的那样循环
  • @Hill ,是的,这样更好:)

标签: java arrays arraylist contains


【解决方案1】:

正如 cmets 所解释的,unusedMoves.contains(move) 无法正常工作。 .contains 方法使用列表内对象的.equals 方法来检查给定值是否等于元素之一。但是,数组的.equals 方法不比较元素,它只比较使用== 的数组的标识。

例如:

int[] arr = {1, 2};

// prints false, as the array in the list is not *identical*
System.out.println(Arrays.asList(new int[]{1, 2}).contains(arr));

// prints true, as the array in the list *is* identical
System.out.println(Arrays.asList(arr).contains(arr));

考虑这个辅助方法:

private boolean contains(List<int[]> list, int[] arr) {
    return list.stream().anyMatch(x -> Arrays.equals(x, arr));
}

使用此辅助方法,您可以将unusedMoves.contains(move) 替换为contains(unusedMoves, move),它应该可以按预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2023-04-05
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多