如何使用Apache commons-lang3编写equals方法?

问题描述 投票:0回答:1
package org.sudoku;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.*;

public class SudokuBoard {
    private final SudokuField[][] board = new SudokuField[9][9];
    private final SudokuSolver solver;
    private final SudokuColumn[] columnObservers = new SudokuColumn[9];
    private final SudokuRow[] rowObservers = new SudokuRow[9];
    private final SudokuBox[] boxObservers = new SudokuBox[9];
    private boolean state = true;

    public SudokuBoard(SudokuSolver solver) {
        this.solver = Objects.requireNonNull(solver);
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                board[i][j] = new SudokuField();
            }
        }
        for (int y = 0; y < 9; y++) {
            List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
            for (int i = 0; i < 9; i++) {
                fields.set(i, board[y][i]);
            }
            rowObservers[y] = new SudokuRow(fields);
        }
        for (int x = 0; x < 9; x++) {
            List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
            for (int i = 0; i < 9; i++) {
                fields.set(i, board[i][x]);
            }
            columnObservers[x] = new SudokuColumn(fields);
        }
        int tableIndex = 0;
        for (int x = 0; x < 9; x  += 3) {
            for (int y = 0; y < 9; y += 3) {
                List<SudokuField> fields = Arrays.asList(new SudokuField[9]);
                int fieldIndex = 0;
                for (int i = x; i < x + 3; i++) {
                    for (int j = y; j < y + 3; j++) {
                        fields.set(fieldIndex, board[i][j]);
                        fieldIndex++;
                    }
                }
                boxObservers[tableIndex] = new SudokuBox(fields);
                tableIndex++;
            }
        }
        int tableIndex2 = 0;
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                board[i][j].setObservers(columnObservers[i], rowObservers[j], boxObservers[tableIndex2]);
                if (j % 3 == 2) {
                    tableIndex2++;
                }
            }
            tableIndex2 = i / 3;
        }
    }

    public void solveGame() {
        solver.solve(this);
    }

    public boolean isSafe() {
        return checkBoard();
    }

    public int get(int y, int x) {
        return board[y][x].getFieldValue();
    }

    public void set(int y, int x, int value) {
        try {
            board[y][x].setFieldValue(value);
        } catch (IllegalArgumentException e) {
            state = false;
        }
    }

    public SudokuRow getRow(int y) {
        return rowObservers[y];
    }

    public SudokuColumn getColumn(int x) {
        return columnObservers[x];
    }

    public SudokuBox getBox(int y, int x) {
        int row = y / 3 * 3;
        int col = x / 3 * 3;
        return boxObservers[col + 3 * row];
    }

    private boolean checkBoard() {
        if (state) {
            return true;
        }
        state = true;
        for (int i = 0; i < 9; i++) {
            state &= columnObservers[i].verify() & rowObservers[i].verify() & boxObservers[i].verify();
        }
        return state;
}
    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                stringBuilder.append(board[i][j].getFieldValue());
                if (j < 8) {
                    stringBuilder.append("  ");
                }
            }
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }
}

我尝试用这种方式编写 equals 方法(如下),但不幸的是它不起作用。我想重写所有数据模型类中的以下方法:

toString()
equals()
hashCode()
方法。

使用外部库来有效地实现它们。

Apache commons-lang3

hashCode() 和 equals() 方法的实现是一致的。当我设置两个板具有相同的值时,equals 方法应该返回 true。

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        SudokuBoard otherBoard = (SudokuBoard) obj;

        return new EqualsBuilder()
                .append(board, otherBoard.board)
                .append(solver, otherBoard.solver)
                .append(columnObservers, otherBoard.columnObservers)
                .append(rowObservers, otherBoard.rowObservers)
                .append(boxObservers, otherBoard.boxObservers)
                .append(state, otherBoard.state)
                .isEquals();
    }
    }
java apache overriding equals hashcode
1个回答
0
投票

我认为你的问题是 one+ 字段与 EqualBuilder 不兼容。具体来说,该类本身没有正确实现

equals()
。由于您不提供这些类的源代码,我们无法知道。

我想也许是二维数组

SudokuField[][] board
。但是看看该实用程序源代码的第 823 行:

https://commons.apache.org/proper/commons-lang//jacoco/org.apache.commons.lang3.builder/EqualsBuilder.java.html

看起来好像正确地递归了。

所以,我要做的就是,将每个

append()
放入

        return new EqualsBuilder()
                .append(board, otherBoard.board)
                .append(solver, otherBoard.solver)
                .append(columnObservers, otherBoard.columnObservers)
                .append(rowObservers, otherBoard.rowObservers)
                .append(boxObservers, otherBoard.boxObservers)
                .append(state, otherBoard.state)
                .isEquals();

并一次删除一个,看看哪一个打破了平等。

您可以做的另一件事是尝试

EqualsBuilder.reflectionEquals(this, obj)
,它应该使用反射遍历整个树深度

© www.soinside.com 2019 - 2024. All rights reserved.