当前位置: 首页 > 知识库问答 >
问题:

获取非重写的equals方法以使用hashCode

袁增
2023-03-14

这是来自与hashCode一起使用的旧版本代码并等于,但我正在尝试让新版本使用它。我认为原因是因为在旧版本中我覆盖了 equals 和 hashCode,但在新版本中我似乎无法做到这一点,因为我不再比较对象,而是比较数组(这是猜测)。因此,当前版本不会拾取重复项。它说没有重复项,但这是不正确的。

以下是检测重复项的旧版本的哈希代码和等于。

private Cube() {
    cube = new int[][] {
        { 0, 0, 0, 0 },
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };

    cube = scanCube(cube);
    cube = print_cube(cube);
}

private Cube(Cube other) {
    cube = new int[other.cube.length][];
    for (int i = 0; i < other.cube.length; i++) {
        cube[i] = Arrays.copyOf(other.cube[i], other.cube[i].length);
    }
}

public boolean isSolved() {
    for (int i = 0; i < cube.length; i++) {
        for (int k = 1; k < cube[i].length; k++) {
            if (cube[i][0] != cube[i][k]) {
                return false;
            }
        }
    }
    return true;
}

@Override
public boolean equals(Object other) {
    return other instanceof Cube && Arrays.deepEquals(((Cube) other).cube, cube);
}


@Override
public int hashCode() {
    return Arrays.deepHashCode(cube);
}`

这是当前版本。

public static void main(String[] args) {

    int[][] cube = new int[][] {
        { 0, 0, 0, 0 },
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };
    cube = scanCube(cube);
    cube = print_cube(cube);
    solve(cube);
}     
private static boolean isSolved(int [][] cube) {
    for (int i = 0; i < cube.length; i++) {
        for (int k = 1; k < cube[i].length; k++) {
            if (cube[i][0] != cube[i][k]) {
                return false;
            }
        }
    }
    return true;
}

public static int[][] copyCube(int [][] cube){
   int [][] copy = new int [6][4];

   for(int i = 0; i < 6; i++ ){
       copy[i] = cube[i].clone();
   }
   return copy;
}

public static boolean equals(int[][] other, int[][] cube) {
    return Arrays.deepEquals(other, cube);
}

public int hashCode(int [][] cube) {
    return Arrays.deepHashCode(cube);
}

在搜索方法中是确定重复项的地方。这是旧的代码。

static public void solve(Cube c) {
    Set<Cube> cubesFound = new HashSet<Cube>();
    cubesFound.add(c);

    Stack<Cube> s = new Stack<Cube>();
    s.push(c);

    Set<Stack<Cube>> initialPaths = new HashSet<Stack<Cube>>();
    initialPaths.add(s);

    solve(initialPaths, cubesFound);
}

static public void solve(Set<Stack<Cube>> livePaths, Set<Cube> cubesFoundSoFar) {
    System.out.println("livePaths size:" + livePaths.size());
    int numDupes = 0;

    Set<Stack<Cube>> newLivePaths = new HashSet<Stack<Cube>>();

    for (Stack<Cube> currentPath : livePaths) {

        Set<Cube> nextStates = currentPath.peek().getNextStates();

        for (Cube next : nextStates) {
            if (currentPath.size() > 1 && next.isSolved()) {
                currentPath.push(next);
                System.out.println("Path length:" + currentPath.size());
                System.out.println("Path:" + currentPath);
                System.exit(0);

            } else if (!cubesFoundSoFar.contains(next)) {
                Stack<Cube> newCurrentPath = new Stack<Cube>();
                newCurrentPath.addAll(currentPath);
                newCurrentPath.push(next);
                newLivePaths.add(newCurrentPath);
                cubesFoundSoFar.add(next);
            } else {
                numDupes += 1;
            }
        }
    }

    System.out.println("Duplicates found " + numDupes + ".");
    solve(newLivePaths, cubesFoundSoFar);
}

还有新的。

static private void solve(int[][] cube) {

    int[][][] s = new int[12][6][4];
    s[0] = cube;

    Set<int[][][]> initialPaths = new HashSet<int[][][]>();
    initialPaths.add(s);
    Set<int[][]> cubesFound = new HashSet<int[][]>();
    cubesFound.add(cube);

    solve(initialPaths, cubesFound, 1);
}

static private void solve(Set<int[][][]> livePaths,Set<int[][]> cubesFoundSoFar, int iterationCount) {
    System.out.println("livePaths size:" + livePaths.size());

    Set<int[][][]> newLivePaths = new HashSet<int[][][]>();
    int counter = 0;
    int recordDepth = 0;
    int duplicates = 0;

    for(int[][][] currentPath : livePaths) {

        Set<int [][]> nextStates = getNextStates(currentPath[iterationCount-1]);

        for (int[][] next : nextStates) {
            if (isSolved(next)) {
                currentPath[iterationCount] = next;
                int maxSteps = -1;
                System.out.println("Path:" );
                for(int i = 0; i < currentPath.length; i++) {
                    if(currentPath[i] != null) {
                        maxSteps = i;
                        System.out.println(toString(currentPath[i]));
                    }else {
                        break;
                    }
                }
                System.out.println("Path length:" + maxSteps);
                System.exit(0);

            } else if(!cubesFoundSoFar.contains(next)){
                int[][][] newCurrentPath = new int[12][6][4];
                newCurrentPath = currentPath.clone();
                newCurrentPath[iterationCount] = next;
                newLivePaths.add(newCurrentPath);
                counter ++;
                cubesFoundSoFar.add(next);
            }  else {
                duplicates += 1;
            }
        }
    }
    //System.out.println(" Set.size(): "+newLivePaths.size());

    String storeStates = "positions.txt";
    try {
        PrintWriter outputStream = new PrintWriter(storeStates);
        outputStream.println(storeStates);
        for(int[][][] s:newLivePaths) {
            outputStream.println(toString(s[iterationCount]));
        }
        outputStream.close();

    } catch (FileNotFoundException e) {
        System.err.println("Fatal: could not open cache file for cube positions. exiting.");
        e.printStackTrace();
        System.exit(1);
    }
    System.out.println("Duplicates found "+ duplicates + ".");
    solve(newLivePaths, cubesFoundSoFar, iterationCount+1);
}

共有1个答案

越伯寅
2023-03-14

您没有在第二个代码中重写< code>equals(Object)方法,但是< code > set . contains(Object)使用< code>equals来比较元素。因为多维数据集中没有对象,所以使用< code>Object的对象。这并不比较内容,它只是测试对象是否是相同的实例(相同的内存位置)。

此处的相关部分包含

...更正式地说,当且仅当此集合包含元素 e 时返回 true,使得 (o==null ? e==null : o.equals(e))。...

您可以在第二个代码中添加类似的内容:

@Override
public boolean equals(Object other) {
    if (other instanceof Cube)
        return equals(cube, ((Cube) other).cube);
    else
        return false;
}


@Override
public int hashCode() {
    return hashCode(cube);
}
 类似资料:
  • 问题内容: 如何覆盖对象类中的equals方法? 即我有 我想将参数obj转换为Person类型,但是如果执行(Person)obj,它将无法正常工作。 问题答案: 您可以将其强制转换为方法,只需使用的实例确保其类型正确

  • 我正在尝试创建一个有理数类并覆盖等于和哈希代码方法。但是我的等号在明显不正确的情况下又回来了,即分子和分母不同。知道是什么原因造成的吗?

  • 本文向大家介绍hashCode 与 equals ?为什么重写equals时必须重写hashCode方法?相关面试题,主要包含被问及hashCode 与 equals ?为什么重写equals时必须重写hashCode方法?时的应答技巧和注意事项,需要的朋友参考一下 面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” ha

  • 本文向大家介绍java中重写equals()方法的同时要重写hashcode()方法(详解),包括了java中重写equals()方法的同时要重写hashcode()方法(详解)的使用技巧和注意事项,需要的朋友参考一下 object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 tr

  • 本文向大家介绍为什么在重写 equals方法的同时必须重写 hashcode方法,包括了为什么在重写 equals方法的同时必须重写 hashcode方法的使用技巧和注意事项,需要的朋友参考一下 我们都知道Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类。 其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值。O

  • 我的问题是关于我被重写的hashCode()方法。我知道,如果equals(Object)方法认为两个对象相等,我需要hashCode()为它们返回相同的值。我的直觉告诉我,在某些情况下,这个hashCode()会违反合同。 有没有一种可接受的方法可以在一个重写的equals(Object)方法中使用equalsIgnoreCase(String)方法,并生成一个不违反约定的hashcode?