Code creating object array and toString method.
import java.util.Arrays;
public class TicTacToeBoard extends BoardClass{
private int turns;
private XOClass[][] a;
public TicTacToeBoard(int rows,int cols){
super(rows,cols);
XOClass[][]a = new XOClass[rows][cols];
turns = 0;
}
public String toString(){
return (Arrays.deepToString(a));
}
}
Object Class
public class XOClass{
private String name;
private static int turn=0;
public XOClass(){
if (turn==0){
this.name = "-";
}
if (turn==1){
this.name = "X";
}
else{
this.name = "O";
}
}
Demo Class
public class play {
public static void main(String[] args){
TicTacToeBoard tac = new TicTacToeBoard(3,3);
System.out.println(tac);
}
}
when calling class play it returns null as there is nothing in the array what am I doing wrong with my code.
In your code:
XOClass[][]a = new XOClass[rows][cols];
You initialize new XOClass its only in the method and when the method end it is distrusting.
change that to
a = new XOClass[rows][cols];
This means you have created a two-dimensional array, with 'rows' rows. In the first row there are 'cols' columns.
and all rows are null.
Now you should create rows like :
a[0] = new XOClass[cols];
And then
a[0][0]=new XOClass();
Related
I'm trying to create a class that will do everything that a different class can do, but it will use random integers in order to create the objects that would normally require user input. Here I have a Pokemon program where I have class where the user creates a Pokemon trainer by inputting their name, and the program will create an ArrayList where the trainer's Pokemon are stored. I have a subclass called ComputerTrainer where it should have the same functionality, but randomly generated Pokemon will be added to the trainer's list of Pokemon. I created a constructor that accesses the protected variables in the PokemonTrainer class, but I'm getting an error that says "reason: actual and formal argument lists differ in length". Why I am getting this error?
Here is the code for the PokemonTrainer class:
import java.util.ArrayList;
public class PokemonTrainer
{
// private constants
private static final int MAX_POKEMON = 2;
protected ArrayList<Pokemon> pokemonList;
protected String name;
protected int numOfPokemon;
// Write your PokemonTrainer class here
public PokemonTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
}
public boolean addPokemon(Pokemon p)
{
if(numOfPokemon < MAX_POKEMON)
{
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
public boolean hasLost()
{
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
if(p.hasFainted())
{
numOfPokemonThatLost++;
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return true;
}
else
{
return false;
}
}
public Pokemon getNextPokemon()
{
int nextPokemon = 0;
int numOfPokemonThatLost = 0;
for(Pokemon p : pokemonList)
{
while(p.hasFainted() && nextPokemon < numOfPokemon)
{
nextPokemon++;
numOfPokemonThatLost++;
if(nextPokemon < numOfPokemon)
{
p = pokemonList.get(nextPokemon);
}
}
}
if(numOfPokemonThatLost == numOfPokemon)
{
return null;
}
else
{
return pokemonList.get(nextPokemon);
}
}
public Pokemon getPokemon(int nPokemon)
{
return pokemonList.get(nPokemon);
}
public int getNumberOfPokemons()
{
return pokemonList.size();
}
public static int getMaxPokemon()
{
return MAX_POKEMON;
}
public String toString()
{
return name;
}
}
and here is the code for the ComputerTrainer subclass:
import java.util.ArrayList;
import java.util.Random;
public class ComputerTrainer extends PokemonTrainer
{
// private constants
// Possible pokemon names and move names to generate random Pokemon
private static final String[] POKEMON_NAMES = {"Pikachu", "Bulbasaur", "Charmander", "Squirtle"};
private static final String[] MOVE_NAMES = {"Tailwhip", "Bodyslam", "Splash", "Shock"};
private static final int MAX_DAMAGE = 25;
private static final int MAX_MOVES = 4;
private PokemonImages images = new PokemonImages();
// Write a Constructor that sets the name of the ComputerTrainer
// and adds 2 randomly generated Pokemon to itself
public ComputerTrainer(String name)
{
this.name = name;
pokemonList = new ArrayList<Pokemon>();
for(int i = 0; i < PokemonTrainer.getMaxPokemon(); i++)
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
}
}
/*
* Adds a randomly generated Pokemon to this ComputerTrainer's
* collection of Pokemon. A ComputerTrainer can only have 2
* Pokemon. This method returns true if there was room for the
* new Pokemon and it was successfully added, false otherwise.
*/
public boolean addRandomPokemon()
{
if(numOfPokemon < PokemonTrainer.getMaxPokemon())
{
Random num = new Random();
int randomNumber = num.nextInt(POKEMON_NAMES.length);
Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
pokemonList.add(p);
numOfPokemon++;
return true;
}
else
{
return false;
}
}
// Returns a Move randomly chosen from the set of Moves
// that this trainer's current Pokemon knows.
// If all Pokemon have fainted, returns null.
public Move chooseRandomMove()
{
Pokemon currentBattlingPokemon = getNextPokemon();
// This method isn't finished yet
}
}
The program outputs the following error:
ComputerTrainer.java:20: error: constructor PokemonTrainer in class PokemonTrainer cannot be applied to given types;
{
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
The problem is that PokemonTrainer only has a constructor that has one String as parameter:
public class PokemonTrainer
{
public PokemonTrainer(String name) {
...
}
but you are not calling that constructor from ComputerTrainer:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
this.name = name;
...
}
}
Java does not automatically call the constructor of the superclass that matches the actual constructor, it calls the default (parameter-less constructor) but the superclass does not have it.
Solution: add an explicit invokation of the correct constructor of the superclass:
public class ComputerTrainer extends PokemonTrainer
{
public ComputerTrainer(String name) {
super(name);
...
}
}
see Java Language Specification 8.8.7. Constructor Body for more details
Note: the error message is a bit confusing since there is like a hidden super() call as first statement in the ComputerTrainer constructor
I'm learning Java and trying out stuff. I want to be able to print students' names with their courses and grades. I have written the following classes to achieve that but since I'm a newbie, I'm wondering if I have done it correctly. The code does display what I want but how can I best optimize it?
Subject class:
public class Subject {
private String subjName;
private int subjGrade;
public Subject(String subjName, int subjGrade) {
this.subjName = subjName;
this.subjGrade = subjGrade;
}
public void setName(String name) {
this.subjName = name;
}
public String getName() {
return subjName;
}
public int getGrade(){
return subjGrade;
}
#Override
public String toString() {
return String.format( getName() + ", Grade:" + getGrade());
}
}
StudentSubJGrade class:
import javax.swing.text.html.HTMLDocument;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class StudentSubJGrade {
String name;
Subject[] subjects;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setSubjects(Subject[] subjects) {
this.subjects = subjects;
}
public StudentSubJGrade(String name, Subject[] subjects) {
this.name = name;
this.subjects = subjects;
}
#Override
public String toString() {
return String.format("Name:" + getName() + " Subjects:" + Arrays.toString(subjects));
}
}
I feel I can add the subjects via the ArrayList but couldn't come up with how to do it after hours of trials. How can this be done without using arrays as I have done?
Driver class:
import java.util.ArrayList;
public class StudentSubjGradeDriver {
public static void main(String[] args) {
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<StudentSubJGrade> test2 = new ArrayList<>();
Subject[] subjects = new Subject[3];
subjects[0] = new Subject("Maths",80);
subjects[1] = new Subject("Physic",90);
subjects[2] = new Subject("Chemistry",70);
Subject[] subjects1 = new Subject[4];
subjects1[0] = new Subject("Maths",80);
subjects1[1] = new Subject("Physic",90);
subjects1[2] = new Subject("Chemistry",70);
subjects1[3] = new Subject("Geography",90);
test.add(new StudentSubJGrade("Anita",subjects));
test2.add(new StudentSubJGrade("James",subjects1));
System.out.println(test);
System.out.println(test2);
}
}
After carrying out suggestions, I tried improving on the code by creating the subjects as ArrayLists but I'm having trouble with it:
ArrayList<Subject> subjects;
public StudentSubJGrade(String name, ArrayList<Subject> subjects) {
this.name = name;
this.subjects = subjects;
}
Now in the main method, I tried the following but I'm getting an error:
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<Subject> st = new ArrayList<>();
st.add(new Subject("Maths",90));
test.add("Anita",st);
The problems with your code are that a) you are passing an array to the constructor without copying it, and b) you cannot change the subjects later.
For example, for a) say that you do the following:
Subject[] subjects = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70),
new Subject("Geography",90)
};
StudentSubJGrade student = new StudentSubJGrade("Hassan", subjects );
So far, so good. But now:
subjects[ 0 ] = null;
And suddenly your StudentSubJGrade student object has a null in its subjects.
This effect has to do with arrays being objects (like Student), instead of value types (as in int x = 5), which implies that in your case both references will point to the same array.
Take look here for a demo on shared array objects.
You can avoid this by changing the method setSubjects().
public void setSubjects(Subject[] subjects)
{
this.copySubjects( subjects );
}
private void copySubjects(Subject[] subjects)
{
final int arraySize = subjects.length;
this.subjects = new Subject[ arraySize ];
System.arraycopy( subjects, 0, this.subjects, 0, arraySize );
}
public StudentSubJGrade(String name, Subject[] subjects) {
this.name = name;
this.copySubjects( subjects );
}
If you need to change the subjects later, then you need to change the array inside the class for an ArrayList, and never expose it. You can get the subjects with the toArray() method, and accept an array or an enumeration to load it.
public void clearSubjects()
{
this.subjects.clear();
}
public void addSubjects(Subject[] subjects)
{
this.appendSubjects( subjects );
}
private void appendSubjects(Subject[] subjects)
{
this.subjects.addAll( subjects );
}
public Subject[] getSubjects()
{
return this.subjects.toArray( new Subject[ 0 ] );
}
public StudentSubJGrade(String name, Subject[] subjects)
{
this.name = name;
this.appendSubjects( subjects );
}
private ArrayList<Subject> subjects;
Hope this helps.
You have to use arrays because the StudentSubJGrade constructor expects the second argument to be a Subject[]. However, you can simplify your creation of the arrays:
import java.util.ArrayList;
public class StudentSubjGradeDriver {
public static void main(String[] args) {
ArrayList<StudentSubJGrade> test = new ArrayList<>();
ArrayList<StudentSubJGrade> test2 = new ArrayList<>();
Subject[] subjects = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70)
};
Subject[] subjects1 = new Subject[] {
new Subject("Maths",80),
new Subject("Physic",90),
new Subject("Chemistry",70),
new Subject("Geography",90)
};
test.add(new StudentSubJGrade("Hassan",subjects));
test2.add(new StudentSubJGrade("James",subjects1));
System.out.println(test);
System.out.println(test2);
}
}
I have been trying to make a game for a friend, but I'm having a problem with getting my line player[i].setName(getName(pn)); in class Players to work. I want to be able to set the names of the players, or change them, in the list. but I keep getting errors at this line. This happened after i changed the public variables in class Player from static.
"Exception in thread "main" java.lang.NullPointerException
at worldhomicide.drinkinggame.PlayerInfo.Players.setPlayers(Players.java:16)
at worldhomicide.drinkinggame.main.Game.main(Game.java:25)"
Any help would be greatly appreciated! I posted all needed code below.
Game Class
public class Game{
public static void main(String[] args) {
MessageHandler.gameRules(); // Display Game Information
Players.getAmount();Players.setPlayers(); // Get player data
System.out.println("What player would you like to look up?");
int choice = Integer.parseInt(EventHandler.keyboard.next()); choice -= 1;
System.out.println(Players.player[choice].name);
}
}
Players Class
public class Players extends EventHandler {
public static int playerAmount;
public static Player[] player;
public static void setPlayers(){
player = new Player[playerAmount];
for(int i = 0; i < player.length; i++){
int pn = i+1;
player[i].setName(getName(pn));
}
}
public static void getAmount(){
MessageHandler.playerAmount();
playerAmount = Integer.parseInt(keyboard.next());
}
}
Class EventHandler
public class EventHandler {
public static Scanner keyboard = new Scanner(System.in);
public static String getName(int playerNumber){
System.out.println("What is player " + playerNumber + "'s name?");
String name = keyboard.next();
return name;
}
}
Player Class
public class Player {
public String name;
public int score;
public void setName(String name){
this.name = name;
}
}
Note that in your setPlayers() method, inside the loop, you didn't create Player object before accessing the player[i].setName() method.
for(int i = 0; i < player.length; i++){
int pn = i+1;
player[i] = new Player(); //you need to create Player object
player[i].setName(getName(pn));
}
I am having a hard time finding out how to write my toString Method to get the output of each of my bears in my program. I want the output to show "Race - Points - TotalPoints". But can't manage to get it right even though the rest of the code seems to compile.
Do i need to have the toString defined in both classes or what am I missing? I have checked a couple of other questions that are resembling and that seems to be an alternativ? But how is it most effectively implemented?
First off the bear class:
import java.util.ArrayList;
public class Bear {
public static void main(String[] args) {
Bear b = new Bear("Sebastian", 100, "Brownbear");
ArrayList <Bear> bears = new ArrayList<Bear>();
bears.add(b);
}
private String name;
private int points;
private String race;
public Bear(String name, int points, String race) {
this.name = name;
this.points = points;
this.race = race;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRace() {
return race;
}
public void setRace(String race) {
this.race = race;
}
public int getInitialPoints() {
return points;
}
public int getPoints() {
int oldPoints = points;
points /= 2;
return oldPoints;
}
}
Secondly the BearCollection class:
import java.util.ArrayList;
public class BearCollection {
ArrayList <Bear> bears = new ArrayList<Bear>();
int totalPoints = 0;
public void add (Bear b) {
for (Bear inCollection : bears) {
if(b.getName().equals(inCollection.getName())) {
return;
}
}
for (Bear inCollection : bears)
if (b.getRace().equals(inCollection.getRace())) {
for(int i = bears.size(); i > 0; i --) {
if(bears.get(i).getRace().equals(b.getRace())) {
b.getPoints();
i = 0;
}
}
}
totalPoints += b.getInitialPoints();
bears.add(b) ;
}
public String toString(){
return ;
}
As you were told, just override the toString method. For performance use StringBuilder, rather than String concatenation.
import java.util.*;
public class ans{
public static void main(String[] args){
Bears bears = new Bears();
bears.add(new Bear());
bears.add(new Bear());
bears.add(new Bear());
System.out.println(bears);
}
}
class Bear{
public String toString(){
return "I am a bear";
}
}
class Bears{
private ArrayList<Bear> bears = new ArrayList<Bear>();
public void add(Bear bear){
bears.add(bear);
}
public String toString(){
StringBuilder str = new StringBuilder();
if(!bears.isEmpty()){ // If there is no bears, return empty string
str.append(bears.get(0)); // Append the first one
for(int index = 1; index < bears.size(); index++){ // For all others
str.append(" - "); // Append a separator and the bear string
str.append(bears.get(index));
}
}
return str.toString();
}
}
Edit To print A-B-C-D, just associate every item with a separator except one. A(-B)(-C)(-D) or (A-)(B-)(C-)D. You could add easily a beginning and a end mark.
overriding the toString in Bear class would resolve the issue.
If you need to print out the entire collection of Bears, you'd need to give Bear a toString, something like:
return "Bear("+name+","+points+","+race+")";
Then, in the toString of BearCollection, just write a for each loop in the toString to go through and call toString on each bear in the collection, printing them out.
I'm getting this error from my code:
Exception in thread "main" java.lang.NullPointerException
at MainClass.main(MainClass.java:20)
Could anyone identify the error, I think it has something to do with initializing my array?
MainClass.java
public class MainClass {
public static void main(String[] args) {
//dummy vars to simulate user input
double price = 2.75;
//declare an array of wincalcs
WinCalc[] staging1;
staging1 = new WinCalc[100];
for (int x=0; x<staging1.length; x++ ) {
staging1[x].price = price;
staging1[x].quantity = x+1;
staging1[x].calcTotal();
}
}
}
WinCalc.java
public class WinCalc {
public double price;
public double quantity;
public double total;
public WinCalc () {
price= 0;
quantity = 0;
total = 0;
}
public void calcTotal() {
this.total = price * quantity;
}
}
You forgot to create the objects
for (int x=0; x<staging1.length; x++ ) {
staging1[x] = new WinCalc();
// ...
}
When you allocate your array, it is initially populated with null entries. In order for it to contain actual objects, you must manually populate will newly allocated objects:
WinCalc[] staging1;
staging1 = new WinCalc[100];
for(int n = 0; n < 100; n ++)
{
stanging1[n] = new WinClac();
}
This is because all objects in java are references which by default point to nowhere.
Update your code with this:
public class MainClass {
public static void main(String[] args) {
//dummy vars to simulate user input
double price = 2.75;
//declare an array of wincalcs
WinCalc[] staging1;
staging1 = new WinCalc[100];
for (int x=0; x<staging1.length; x++ ) {
staging1[x] = new WinCalc();
staging1[x].price = price;
staging1[x].quantity = x+1;
staging1[x].calcTotal();
}
}
Cases that we get NullPointerException are accessing/modifying the field of null object or accessing/modifying the slot of null as if it were an array or taking the length of null as if it were an array.
//Let us have a Person class
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString(){
return "[Name->"+ getName() +" ,Age->"+getAge()+"]";
}
}
//The main class simulate collection of persons using array
import java.util.Arrays;
public class ListOfPersonIn {
public static void arrayManipulation()
{
Person[] persons=new Person[3]; // Array of Person to conatain 3 persons
Person titi=new Person("Titi", 35);
Person beti=new Person("Beti", 10);
Person nati=new Person("nati", 18);
// Display list of persons
for(Person person:persons){
System.out.println(person.toString());
}
//Double array size, copy the old value to the new array and add new persons
Person[]newPersons=copyArraySize(persons);
System.out.println("Loop through a new Array ");
for(Person person: newPersons){
System.out.println(person.toString());
}
}
// Private method to resize array, copy the old array to the new array and add new list of persons
private static Person [] copyArraySize(Person [] persons)
{
Person[]newPersons=Arrays.copyOf(persons, persons.length*2);
// newPersons[persons.length]=new Person("meti", 50); in this case we get NullPointerException because the new array has length 6 but only 4 data is populated the reaming 2 indices are not populated i.e newArray[4] and newArray[5] are null value so it raised NullPointerException. Not to get NullPointerException just populate all array indices with data
for(int i=persons.length;i< newPersons.length;i++){
newPersons[i]=new Person("meti", 50);//duplicate data, array can’t maintain uniqueness like set
}
return newPersons;
}
public static void main(String[] args) {
arrayManipulation();
}
}