In my app I'm writing/reading an arrayList of objects that contain objects within them as well. (A list of BingoPages that contain BingoCells, both of which implement Serializable). The log works fine when printing values inside one of the BingoPages objects in the list, but when I call a method that deals with the inner BingoCells I get a null pointer exception. Any help greatly appreciated, been trying to get this save/load to work for too long!
My saveAll() method to save the data contains the following code:
String fileName = "bingoPages";
FileOutputStream outputStream;
try
{
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(allSheets);
oos.flush();
oos.close();
}
And my readAll() to load the data contains the following:
try
{
FileInputStream in = openFileInput("bingoPages");
ObjectInputStream ois = new ObjectInputStream(in);
allSheets = (ArrayList<BingoPage>)ois.readObject();
ois.close();
}
catch(Exception e)
{
allSheets = new ArrayList<BingoPage>();
}
Edit: Adding the code for the classes I am saving.
The simple BingoCell is as follows:
public class BingoCell implements Serializable{
public int num;
public int called;
public BingoCell(int id)
{
num = id;
called = 0;
}
}
And the BingoPage class:
public class BingoPage implements Serializable{
public int pageID;
public BingoCell[][] table;
public int index;
public String winnerLocation;
public BingoPage(int id)
{
table = new BingoCell[5][5];
pageID = id;
winnerLocation = null;
//the free space
table[2][2] = new BingoCell(999);
table[2][2].called = 1;
}
public void insertNum(int num, int column, int row)
{
table[row][column] = new BingoCell(num);
}
public String stringMe()
{
StringBuilder test = new StringBuilder();
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
test.append(table[i][j].num);
test.append(" | ");
}
test.append("\n\r");
}
return test.toString();
}
public void markNum(int markNum, int idx)
{
index = idx;
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
if(table[i][j].num == markNum)
{
table[i][j].called = 1;
checkForBingo();
}
}
}
}
private void checkForBingo()
{
testRows();
testColumns();
testDiagonals();
}
private void testRows()
{
int hasBingo = 1;
for(int i = 0; i < 5; i++)
{
hasBingo = 1;
for(int j = 0; j < 5; j++)
{
if(table[i][j].called == 0)
{
hasBingo = 0;
break; //Skip to the next column
}
}
if(hasBingo == 1)
{
//Alert that bingo on row i+1 if page pageID
alertWinner("Column " + (i+1));
}
}
}
private void testColumns()
{
int hasBingo = 1;
for(int i = 0; i < 5; i++)
{
hasBingo = 1;
for(int j = 0; j < 5; j++)
{
if(table[j][i].called == 0)
{
hasBingo = 0;
break; //row
}
}
if(hasBingo == 1)
{
//Alert that bingo on row i+1 if page pageID
alertWinner("Row " + (i+1));
}
}
}
private void testDiagonals()
{
if(table[0][0].called == 1 && table[1][1].called == 1 && table[2][2].called == 1
&& table[3][3].called == 1 && table[4][4].called == 1)
{
//Top left->bottom right bingo!
alertWinner("Top left->bottom right diagonal");
}
else if(table[0][4].called == 1 && table[1][3].called == 1 && table[2][2].called == 1
&& table[3][1].called == 1 && table[4][0].called == 1)
{
//Top right->bottom left bingo!
alertWinner("Top right->bottom left diagonal");
}
}
private void alertWinner(String location)
{
winnerLocation = new String(pageID + " at " + index + " sheets from bottom; location: " + location);
}
public void clear()
{
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
table[i][j].called = 0;
}
}
winnerLocation = null;
}
catch(Exception e)
{
allSheets = new ArrayList<BingoPage>();
}
The problem is surely here. Handling an exception by ignoring it and creating a dummy object instead is no way to debug your code, or even to write it in the first place. You should print the stack trace at this point and fix whatever the problem is.
Related
I have a homework that the teacher test if it's corrects by checking it's output using this website moodle.caseine.org, so to test my code the program execute these lines and compare the output with the expected one, this is the test :
Tas t = new Tas();
Random r = new Random(123);
for(int i =0; i<10000;i++)t.inser(r.nextInt());
for(int i =0;i<10000;i++)System.out.println(t.supprMax());
System.out.println(t);
And my Heap (Tas) class:
package td1;
import java.util.ArrayList;
import java.util.List;
public class Tas {
private List<Integer> t;
public Tas() {
t = new ArrayList<>();
}
public Tas(ArrayList<Integer> tab) {
t = new ArrayList<Integer>(tab);
}
public static int getFilsGauche(int i) {
return 2 * i + 1;
}
public static int getFilsDroit(int i) {
return 2 * i + 2;
}
public static int getParent(int i) {
return (i - 1) / 2;
}
public boolean estVide() {
return t.isEmpty();
}
#Override
public String toString() {
String str = "";
int size = t.size();
if (size > 0) {
str += "[" + t.get(0);
str += toString(0);
str += "]";
}
return str;
}
public boolean testTas() {
int size = t.size();
int check = 0;
if (size > 0) {
for (int i = 0; i < t.size(); i++) {
if (getFilsGauche(i) < size) {
if (t.get(i) < t.get(getFilsGauche(i))) {
check++;
}
}
if (getFilsDroit(i) < size) {
if (t.get(i) < t.get(getFilsDroit(i))) {
check++;
}
}
}
}
return check == 0;
}
public String toString(int i) {
String str = "";
int size = t.size();
if (getFilsGauche(i) < size) {
str += "[";
str += t.get(getFilsGauche(i));
str += toString(getFilsGauche(i));
str += "]";
}
if (getFilsDroit(i) < size) {
str += "[";
str += t.get(getFilsDroit(i));
str += toString(getFilsDroit(i));
str += "]";
}
return str;
}
//insert value and sort
public void inser(int value) {
t.add(value);
int index = t.size() - 1;
if (index > 0) {
inserCheck(index); // O(log n)
}
}
public void inserCheck(int i) {
int temp = 0;
int parent = getParent(i);
if (parent >= 0 && t.get(i) > t.get(parent)) {
temp = t.get(parent);
t.set(parent, t.get(i));
t.set(i, temp);
inserCheck(parent);
}
}
//switch position of last element is list with first (deletes first and return it)
public int supprMax() {
int size = t.size();
int max = 0;
if (size > 0) {
max = t.get(0);
t.set(0, t.get(size - 1));
t.remove(size - 1);
supprMax(0);
}
else {
throw new IllegalStateException();
}
return max;
}
public void supprMax(int i) {
int size = t.size();
int temp = 0;
int index = i;
if (getFilsGauche(i) < size && t.get(getFilsGauche(i)) > t.get(index)) {
index = getFilsGauche(i);
}
if (getFilsDroit(i) < size && t.get(getFilsDroit(i)) > t.get(index)) {
index = getFilsDroit(i);
}
if (index != i) {
temp = t.get(index);
t.set(index, t.get(i));
t.set(i, temp);
supprMax(index);
}
}
public static void tri(int[] tab) {
Tas tas = new Tas();
for (int i = 0; i < tab.length; i++) {
tas.inser(tab[i]);
}
for (int i = 0; i < tab.length; i++) {
tab[i] = tas.supprMax();
}
}
}
The last 3 lines of the test are :
-2145024521
-2147061786
-2145666206
But the last 3 of my code are :
-2145024521
-2145666206
-2147061786
The problem are probably with the inser and supprMax methods.
I hate to get a bad grade just because of 3 lines placement, because it is a program that verify the code, it dosn't care the the solution was close, it's still says it's wrong.
I am solving this challenge: https://open.kattis.com/problems/virtualfriends
My solution seems to be working but kattis's test cases are running too slowly so I was wondering how I can improve code efficiency. I am using a custom made union-find structure to do this, storing "friends" into a treemap to reference.
import java.util.*;
public class virtualfriends {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int testcases = scan.nextInt();
scan.nextLine();
for (int i= 0; i < testcases; i++) {
int numFriendships = scan.nextInt();
scan.nextLine();
TreeMap<String , Integer> map = new TreeMap<String , Integer>();
int cnt = 0;
UF unionFind = new UF(50000);
for (int j = 0; j < numFriendships; j++)
{
String p1 = scan.next();
String p2 = scan.next();
if (!map.containsKey(p1)) map.put(p1, cnt++);
if (!map.containsKey(p2)) map.put(p2, cnt++);
unionFind.unify(map.get(p1), map.get(p2));
System.out.printf("%d\n", unionFind.getSetSize(map.get(p2)));
}
}
}
static class UF{
private int[] id, setSize;
private int numSets;
public UF(int size) {
id = new int[size] ;
setSize = new int[size];
numSets = size;
for(int i = 0 ; i < size ; ++i) {
id[i] = i;
setSize[i] = 1;
}
}
int find(int i )
{
int root = i;
while (root != id[root]) {
root = id[root];
}
while (i != root) {
int newp = id[i];
id[i] = root;
i = newp;
}
return root;
}
boolean isConnected(int i , int j) {
return find(i) == find(j);
}
int getNumSets() {
return numSets;
}
int getSetSize(int i) {
return setSize[find(i)];
}
boolean isSameSet(int i, int j) {
return find(i) == find(j);
}
void unify(int i, int j)
{
int root1 = find(i);
int root2 = find(j);
if (root1 == root2) return;
if (setSize[root1] < setSize[root2])
{
setSize[root2] += setSize[root1];
id[root1] = root2;
} else {
setSize[root1] += setSize[root2];
id[root2] = root1;
}
numSets--;
}
}
}
I am working on a Four in a row game.
But I have run into a problem with it. I have been able to make the game work. But I would like to know if I can move my public void fillBoard() and public void presentBoard() into another class. This is because I would like to make the code more organised.
package com.company;
public class Main {
public static void main(String[] args)
{
GameMechanics game = new GameMechanics();
game.play();
}
}
package com.company;
import java.util.Scanner;
public class GameMechanics
{
/*
This is my local variables
*/
public Scanner scanner = new Scanner(System.in);
public char token;
public int column;
public int player = 2;
public int turn = 2;
public int count = 0;
public boolean gameRunning = true;
public void play()
{
this.createBoard();
//While gameRunning is true, the methods inside the { } will run, and that's the 4InARow game
while (gameRunning)
{
this.presentBoard();
this.changeTurn();
this.dropToken();
this.gameWon();
}
presentBoard();
}
public void gameWon()
{
this.winConHorizontal();
this.winConVertical();
}
private char[][] board = new char[6][7];
//Creating my board and assign "space" to all the fields in the array.
public void createBoard() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
board[i][j] = ' ';
}
}
}
//Presents the board, it prints the board with |"space"| so it looks more like a gameboard.
public void presentBoard() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (j == 0) {
System.out.print("|");
}
System.out.print(board[i][j] + "|");
}
System.out.println();
}
}
public void changeTurn() {
if (this.turn == this.player) {
this.turn = 1;
this.token = 'X';
} else {
this.turn++;
this.token = 'O';
}
}
public void dropToken() {
System.out.println("player " + turn + ": press 1-7 to drop the token");
column = scanner.nextInt() - 1;
//If pressed any intValue outside the board, it will tell you to try again.
if (column >= 7 || column <= -1)
{
System.out.println("place the token inside the bord");
changeTurn();
} else {
//Drops the token and replace it with playerChar.
for (int i = 5; i > -1; i--) {
if (board[i][column] == ' ')
{
board[i][column] = token;
break;
}
}
}
}
public boolean winConHorizontal() {
while (gameRunning) {
for (int i = 0; 6 > i; i ++) {
for (int j = 0; 7 > j; j ++) {
if (board[i][j] == this.token) {
count ++;
} else {
count = 0;
}
if (count >= 4) {
System.out.println("player " + (turn) + " Wins!!!!");
gameRunning = false;
}
}
}
break;
}
return gameRunning;
}
public boolean winConVertical() {
while (gameRunning) {
for (int i = 0; 7 > i; i ++) {
for (int j = 0; 6 > j; j ++) {
if (board[j][i] == this.token) {
count ++;
} else {
count = 0;
}
if (count >= 4) {
System.out.println("player " + (turn) + " Wins!!!!");
gameRunning = false;
}
}
}
break;
}
return gameRunning;
}
}
An easy way to do this is as follows:
extract your char[][] board into its own class, e.g. Board
Said class could expose the function char getField(int index)
Extract the ,,presenting" part of your code into another class, e.g. BoardPresenter. Said class should have a function presentBoard(Board board) which internally uses getField(int index) of the Board class.
By doing this you abstract away your internal board storage mechanism while also reducing the number of responsibilities the GameMechanics class has (See https://en.wikipedia.org/wiki/Single_responsibility_principle)
yes, you can make another class and extend it with the current class GameMechanics and inside another class you can define the functions.
Note : This is a very simple approachable way.
Otherwise better if you manage your classes and interfaces similar to mvc model, for which you can search youtube for mvc structure java.
I want to print every possible combinations by using given letters without change letter orders so i wrote this code but it will print every line again and again what is the problem
public class Solutions {
public static void main(String[] args) {
// Scanner scanner = new Scanner(System.in);
c = "l u k".split(" ");
Solutions solutions = new Solutions();
solutions.combi(0);
System.out.println("Number of combi = " + count);
System.out.print(max);
}
static String[] c;
static int count = 0;
static int max = 0;
public void combi(int start) {
int j;
if (start != 0) {
String str = "";
for (int i = 0; i < start; i++) {
// System.out.print(c[i]);
str += c[i];
}
// System.out.println();
count++;
}
for (j = start; j < c.length; j++) {
combi(start + 1);
}
}
}
public void combi(int start) {
int j;
if (start != 0) {
for (int i = 0; i < start; i++) {
System.out.print(c[i]);
}
System.out.println();
count++;
} else {
for (j = start+1; j <= c.length; j++) {
combi(j);
}
}
}
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Stack;
public class TSPNearestNeighbour {
{
private final Stack<Integer> stack;
private int numberOfNodes;
public TSPNearestNeighbour()
{
stack = new Stack<Integer>();
}
public void tsp(int adjacencyMatrix[][])
{
numberOfNodes = adjacencyMatrix[1].length - 1;
int[] visited = new int[numberOfNodes + 1];
visited[1] = 1;
stack.push(1);
int element, dst = 0, i,cost=0;
int min = Integer.MAX_VALUE;
boolean minFlag = false;
System.out.print(1 + "\t");
while (!stack.isEmpty())
{
element = stack.peek();
i = 1;
min = Integer.MAX_VALUE;
while (i <= numberOfNodes)
{
if (adjacencyMatrix[element][i] > 1 && visited[i] == 0)
{
if (min > adjacencyMatrix[element][i])
{
min = adjacencyMatrix[element][i];
cost=cost+adjacencyMatrix[element][i];
dst = i;
minFlag = true;
}
}
i++;
}
if (minFlag)
{
visited[dst] = 1;
stack.push(dst);
System.out.print( dst + "\t");
minFlag = false;
continue;
}
stack.pop();
}
System.out.println("total cost" +cost);
}
public static void main(String args[])
{
int number_of_nodes;
Scanner scanner = null;
try
{
System.out.println("Enter the number of nodes in the graph");
scanner = new Scanner(System.in);
number_of_nodes = scanner.nextInt();
int adjacency_matrix[][] = new int[number_of_nodes + 1][number_of_nodes + 1];
System.out.println("Enter the adjacency matrix");
for (int i = 1; i <= number_of_nodes; i++)
{
for (int j = 1; j <= number_of_nodes; j++)
{
adjacency_matrix[i][j] = scanner.nextInt();
}
}
for (int i = 1; i <= number_of_nodes; i++)
{
for (int j = 1; j <= number_of_nodes; j++)
{
if (adjacency_matrix[i][j] == 1 && adjacency_matrix[j][i] == 0)
{
adjacency_matrix[j][i] = 1;
}
}
}
System.out.println("the citys are visited as follows");
TSPNearestNeighbour tspNearestNeighbour = new TSPNearestNeighbour();
tspNearestNeighbour.tsp(adjacency_matrix);
} catch (InputMismatchException inputMismatch)
{
System.out.println("Wrong Input format");
}
scanner.close();
}
}
> illegal start of expression in the line:
> **private final Stack<Integer> stack;**
You have 2 open braces
public class TSPNearestNeighbour { {
remove one and may be you get your code compiled