Sudoku solver recursive backtrack in Java I am implementing recursive backtracking algorithm for sudoku. Below is the code to create board with random filling. I wonder if I can make it better in any terms of readable coding especially validation methods. in Board class. 

public class Board {
private int[][] board;
public final static int SIZE = 9;

public Board() {
    create();
}

public int[][] getBoard() {
    return board;
}

private void create() {
    int openspots = 20;
    board = new int[SIZE][SIZE];
    Random rand = new Random();
    int random, randomrow, randomcolumn;

    while (openspots-- &gt; 0) {
        random = rand.nextInt(SIZE) + 1;
        randomrow = rand.nextInt(SIZE);
        randomcolumn = (rand.nextInt(SIZE));

        if (board[randomrow][randomcolumn] == 0) {
            board[randomrow][randomcolumn] = random;
            int count = 0;

            while (!isValid(randomrow, randomcolumn)) {
                if (count++ == 9) {
                    board[randomrow][randomcolumn] = 0;
                    openspots++;
                    break;
                }

                random = rand.nextInt(SIZE) + 1;
                board[randomrow][randomcolumn] = random;
            }
        }
    }
}

public void printBoard() {
    for (int row = 0; row &lt; SIZE; row++) {
        for (int column = 0; column &lt; SIZE; column++) {
            System.out.print(board[row][column] + " ");
        }
        System.out.println();
    }
}

public boolean isValid(int row, int column) {
    return isValidRow(row) &amp;&amp; isValidColumn(column) &amp;&amp; isValidBlock(row, column);
}

private boolean isValidRow(int row) {
    if (row &gt; 8 || row &lt; 0)
        throw new IllegalArgumentException("Row must be between 0 and " + (SIZE - 1) + " inclusive!");

    Set&lt;Integer&gt; set = new HashSet&lt;&gt;();

    for (int i = 0; i &lt; SIZE; i++) {
        if (board[row][i] != 0 &amp;&amp; set.contains(board[row][i])) {
            return false;
        } else {
            set.add(board[row][i]);
        }
    }

    return true;
}

private boolean isValidColumn(int column) {
    if (column &gt; 8 || column &lt; 0)
        throw new IllegalArgumentException("Column must be between 0 and " + (SIZE - 1) + " inclusive!");

    Set&lt;Integer&gt; set = new HashSet&lt;&gt;();

    for (int i = 0; i &lt; SIZE; i++) {
        if (board[i][column] != 0 &amp;&amp; set.contains(board[i][column])) {
            return false;
        } else {
            set.add(board[i][column]);
        }
    }

    return true;
}

private boolean isValidBlock(int row, int column) {
    if (column &gt; 8 || column &lt; 0)
        throw new IllegalArgumentException("Column must be between 0 and " + (SIZE - 1) + " inclusive!");

    int blockrow = (row / 3) * 3;
    int blockcolumn = (column / 3) * 3;

    Set&lt;Integer&gt; set = new HashSet&lt;&gt;();

    for (int i = 0; i &lt; 3; i++) {
        for (int j = 0; j &lt; 3; j++) {
            if (board[blockrow + i][blockcolumn + j] != 0 &amp;&amp; set.contains(board[blockrow + i][blockcolumn + j])) {
                return false;
            } else {
                set.add(board[blockrow + i][blockcolumn + j]);
            }
        }
    }

    return true;
}
}


The one below is the solver class which has the main algorithm to solve sudoku. 

public class Solver {

public boolean solve(Board board) {
    int[][] boardarr = board.getBoard();

    for (int i = 0; i &lt; board.SIZE; i++) {
        for (int j = 0; j &lt; board.SIZE; j++) {
            if (boardarr[i][j] == 0) {
                for (int k = 1; k &lt;= board.SIZE; k++) {
                    boardarr[i][j] = k;
                    if (board.isValid(i,j) &amp;&amp; solve(board)) {
                        return true;
                    }
                    boardarr[i][j] = 0;
                }
                return false;
            }
        }
    }

    return true;
}
}
Object Orientated Programming

you don't use object orientated programming! that would clean up the code in a large scale

public class Board {
    //private int[][] board; primitive obsession - use objects instead
    private Field[][] fields;
    private Column[] columns;
    private Row[] rows;
    private Block[] blocks;
    public final static int SIZE = 9;  

    ...      
}


you could provide the proper methods for the field - so you could easily represent the field - instead of trying to interpret an int value.

you could provide methods that are specific for these objects - you could even define an interface for common code, like isFieldValid(Field candidate) for Row, Column and Block 

Naming

consider these names and you might find better

Random rand = new Random();
int random, randomrow, randomcolumn;


maybe it would be 

Field candidate;


again here, in Java we don't use the hungarian notation and name a variable by it's type:

//int[][] boardarr = board.getBoard();
int[][] board = board.getBoard(); //would be better
Field[][] fields = board.getFields(); //even more better


Data Structure

if you would use Objects for your Sudoku-Solver you could re-use values (here an example snippet for Block)

class Block {
    final private Set&lt;Field&gt; fields = new HashSet&lt;&gt;();

    boolean isFieldValid(Field field) {
        //Set&lt;Integer&gt; set = new HashSet&lt;&gt;(); we already have such set 
        //and don't need to create a new one whenever we check
        return !fields.contains(field);
    }
}


Magic numbers

you already provide a SIZE = 9 constant - so why don't you use a proper one for the block size?

int blockrow = (row / 3) * 3;
int blockcolumn = (column / 3) * 3;


Testing

i assume you provide enough tests but just don't put these in the question

Summary

very nice piece of code - i'm glad you have posted it here! The algorithm seems straight forward, i like it! The OO-thing is the only flaw here. I would appreciate if you would provide another question with applied OOP!