This is my method to updateHighScoreRecords():
public GameRecord[] updateHighScoreRecords(GameRecord[] highScoreRecords, String name, int level, int score) {
GameRecord[] gameRecord = null;
if (highScoreRecords.length == 0) { // Rule one
gameRecord = new GameRecord[1];
gameRecord[0].setName(name);
gameRecord[0].setLevel(level);
gameRecord[0].setScore(score);
System.out.println("Role one Done");
}
return gameRecord;
}
And this is my GameRecord class:
public class GameRecord {
private String name;
private int level;
private int score;
public GameRecord(String name, int level, int score) {
this.name = name;
this.level = level;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
But there is a nullPointer exception on this line:
gameRecord[0].setName(name);
Why?
I want to return an array of GameRecord type when highScoreRecords length is zero.
You never initialized zeroth element. First you have to add element at zero position and then access it.
gameRecord[0] = new GameRecord();
gameRecord[0].setName(name);
When you wrote
gameRecord = new GameRecord[1];
That means you are just initializing an array to store 2 GameRecord elements. Nothing else. Initially those are null's. You need to initialize each element to use them further. Otherwise they are still null.
Related
I have a program to enter the student's name, gender, grade, and rank
Here is my code:
public class Exercise_W28 {
String name;
String Sex;
int Score;
String ratting;
public Exercise_W28(String name, String Sex,
int Score, String ratting)
{
this.name = name;
this.Sex = Sex;
this.Score = Score;
this.ratting = ratting;
}
public String getName()
{
return name;
}
public String getSex()
{
return Sex;
}
public int getScore()
{
return Score;
}
public String getratting()
{
return ratting;
}
public String toString()
{
return("Name: "+ this.getName()+
".\nSex: "+ this.getSex()+
".\nScore: "+ this.getScore()+
".\nRank: "+ this.getratting()+"."
);
}
public static void main(String[] args)
{
Exercise_W28 std = new Exercise_W28("Jullien","male", 9, "RankA");
System.out.println(std.toString());
} }
Now I want to not put the rank in, but based on the score to determine the rank 1~5 : rankC, 5~7: rankD, 8~10: rankA.
I just learned about classes in java and I don't know how to handle it
You can remove the Rank from constructor and basis on the score passed, initialize the Rank value in constructor itself !
For e.g.
public Exercise_W28(String name, String Sex,
int Score)
{
this.name = name;
this.Sex = Sex;
this.Score = Score;
// if(score == 5)
{
ratting="Rank C" ; //so on and so forth
}
If the logic is too long, consider defining it in another method which returns Rank in String form!
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 2 years ago.
I am trying to create an ArrayList that reads a .csv file, processes the data into an ArrayList, and then print the list out.
My code so far.
The BankRecords class
import java.io.*;
import java.util.*;
public class BankRecords
{
String sex, region, married, save_act, current_act, mortgage, pep;
int children;
double income;
private String id;
private int age;
public BankRecords(String gender, String area, String marriage, String SaveAccount, String CurrentAccount, String HouseBill, String pepp, int minors, double paycheck, String identification, int years)
{
this.sex = gender;
this.region = area;
this.married = marriage;
this.save_act = SaveAccount;
this.current_act = CurrentAccount;
this.mortgage = HouseBill;
this.pep = pepp;
this.children = minors;
this.income = paycheck;
this.id = identification;
this.age = years;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getRegion()
{
return region;
}
public void setRegion(String region)
{
this.region = region;
}
public String getMarried()
{
return married;
}
public void setMarried(String married)
{
this.married = married;
}
public String getSave_act()
{
return save_act;
}
public void setSave_act(String save_act)
{
this.save_act = save_act;
}
public String getCurrent_act()
{
return current_act;
}
public void setCurrent_act(String current_act)
{
this.current_act = current_act;
}
public String getMortgage()
{
return mortgage;
}
public void setMortgage(String mortgage)
{
this.mortgage = mortgage;
}
public String getPep()
{
return pep;
}
public void setPep(String pep)
{
this.pep = pep;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public int getChildren()
{
return children;
}
public void setChildren(int children)
{
this.children = children;
}
public double getIncome()
{
return income;
}
public void setIncome(double income)
{
this.income = income;
}
}
The Client abstract class
import java.io.*;
import java.util.*;
public abstract class Client
{
static ArrayList<List<String>> BankArray = new ArrayList<>(25);
static BankRecords robjs[] = new BankRecords[600];
public static void readData()
{
try
{
BufferedReader br;
String filepath = "C:\\Users\\eclipse-workspace\\Bank_Account\\src\\bank-Detail.csv";
br = new BufferedReader(new FileReader (new File(filepath)));
String line;
while ((line = br.readLine()) != null)
{
BankArray.add(Arrays.asList(line.split(",")));
}
}
catch (Exception e)
{
e.printStackTrace();
}
processData();
}
public static void processData()
{
int idx=0;
for (List<String> rowData: BankArray)
{
robjs[idx] = new BankRecords(null, null, null, null, null, null, null, idx, idx, null, idx);
robjs[idx].setId(rowData.get(0));
robjs[idx].setAge(Integer.parseInt(rowData.get(1)));
idx++;
}
printData();
}
public static void printData()
{
System.out.println("ID\tAGE\tSEX\tREGION\tINCOME\tMORTGAGE");
int final_record = 24;
for (int i = 0; i < final_record; i++)
{
System.out.println(BankArray.get(i) + "\t ");
}
}
}
The BankRecordsTest class (extends Client)
import java.util.*;
import java.io.*;
public class BankRecordsTest extends Client
{
public static void main(String args [])
{
readData();
}
}
The error
And here is the error.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at java.util.Arrays$ArrayList.get(Unknown Source)
at Client.processData(Client.java:33)
at Client.readData(Client.java:24)
at BankRecordsTest.main(BankRecordsTest.java:7)
I'm not sure what the index problem is. Do note that if you run the ReadData() and PrintData() functions separately, the code runs fine but the ProcessData() method causes issues.
I think your data is likely not clean and you are making assumptions about the length of your array. The error you are getting stems from this line:
robjs[idx].setAge(Integer.parseInt(rowData.get(1)));
Clearly, rowData doesn't have 2 items (or more). This is why you are getting ArrayIndexOutOfBoundsException. So you want to check where your variable was initialized. You quickly realize it comes from
for (List<String> rowData: BankArray)
So then, the following question is where BankArray gets initialized. That happens in 2 places. First of all
static ArrayList<List<String>> BankArray = new ArrayList<>(25);
You are creating an empty list. So far so good. Note that you don't need to (and therefore shouldn't) initialize with a size. Lists are not like arrays insofar as they can easily grow and you don't need to give their size upfront.
The second place is
BankArray.add(Arrays.asList(line.split(",")));
This is likely where the issue comes from. Your row variable contains the results of Arrays.asList(line.split(",")). So the size of that list depends on the number of commas in that string you are reading. If you don't have any commas, then the size will be 1 (the value of the string itself). And that's what leads me to concluding you have a data quality issue.
What you should really do is add a check in your for (List<String> rowData: BankArray) loop. If for instance, you expect 2 fields, you could write something along the lines of:
if (rowData.size()<2){
throw new Exception("hmmm there's been a kerfuffle');
}
HTH
I have created a simple Queue of type which is also contains a print() function to it.
public class ArrayQueue implements Queue {
private T[] theArray;
private int currentSize;
private int front;
private int back;
private static final int DEFAULT_CAPACITY = 10;
public ArrayQueue() {
theArray = (T[]) new Object[DEFAULT_CAPACITY];
currentSize = 0;
front = 0;
back = -1;
}
public boolean isEmpty() {
return currentSize == 0;
}
public T dequeue() throws EmptyQueueException {
if (isEmpty())
throw new EmptyQueueException("ArrayQueue dequeue error");
T returnValue = theArray[front];
front = increment(front);
currentSize--;
return returnValue;
}
public void enqueue(T x) {
if (currentSize == theArray.length)
doubleQueue();
back = increment(back);
theArray[back] = x;
currentSize++;
}
private int increment(int x) {
if (++x == theArray.length)
x = 0;
return x;
}
public void print() {
if (isEmpty()) {
System.out.printf("Empty queue\n");
return;
}
System.out.printf("The queue is: ");
for (int i = front; i != back; i = increment(i)) {
System.out.print(theArray[i] + " ");
}
System.out.print(theArray[back] + "\n");
}
I have also created a Song object with 3 variables
public class Song {
private int id;
private String name;
private int likes;
public Song() {
this(1,"Test",10);
}
public Song(int id,String name, int likes) {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLikes() {
return likes;
}
public void setLikes(int likes) {
this.likes = likes;
}
Is there a way modify this function in order to print a specific object's information or do i need to write a different print method during my implementation?
For example i would like my Print method to show all the objects variables , if i call just like this is will only get the object pointer
ArrayQueue<Song> arrayQueue = new ArrayQueue<Song>();
Queue<Song> queue = arrayQueue; //arrayQueue instance is also a Queue
Song s = new Song();
arrayQueue.enqueue(s);
arrayQueue.print();
Result is
The queue is: Song#15db9742
My modification would print :
The queue is : 1 Test 10
You need to override the toString() method of Song.
For example, add this to Song:
#Override
public String toString() {
return id + " " + name + " " + likes;
}
I believe my code is wrong but could someone correct me on my error. I am trying to deep clone an array of objects but class A doesn't seem to be a deep copy as i am having trouble with it. Could some please help. I have trouble copying the array A.
Class A implements Cloneable{
private int year;
private double data;
A(int year, double data)
{
setInt(year);
setDouble(data);
}
public void setInt(int year)
{
this.year = year;
}
public void setDouble(double data)
{
this.data = data;
}
public int getYear()
{
return year;
}
public double getData()
{
return data;
}
public Object clone()
{
A clonedA = new A(this.getYear(), this.getData());
return clonedA;
}}
class B implements Cloneable{
private A[] a;
private String name;
private int arraylength;
private int index;
public B(String name, int length)
{
this.name = name;
this.arraylength = length;
a = new A[array.length];
index = 0;
}
public void addToA(int year, double data)
{
a[index] = new A(year, data);
index++;
}
public String getName(){
return name; }
public int getLength(){
return array length;}
public void setName(String name)
{
this.name= name
}
public Object clone()
{
B clonedB = new B(this.getName(), this.getLength());
for(A clonedArray: a)
{
clonedB.addToA(clonedArray.getYear(), clonedArray.getData());
}
return clonedB;
}
Your clone method in class B seems to be wrong:
I suggest you do sth like
public Object clone()
{
B newB = new B(this.getName(), this.getLength());
for(int i =0;i<newB.a.length;i++)
{
newB.a[i] = a[i];
}
return newB;
}
You could also try a copy constructor;
How to solve the following constructor overloading problem? This is an interview question but I am curious to know the solution.
class Player
{
int nationalRank;
int internationalRank;
String name;
Player(String name, int nationalRank)
{
this.name= name;
this.nationalRank = nationalRank;
this.internationalRank=0;
}
Player(String name, int internationalRank)
{
this.name= name;
this.nationalRank = 0;
this.internationalRank=internationalRank;
}
}
Here, the compiler will give an error because argument types are same for both constructor. But logically they both are different. How can I solve this problem without adding any extra arguments? Is there any design pattern specifically for this?
class Player
{
int nationalRank;
int internationalRank;
String name;
private Player(){}
public static Builder builder()
{
return new Builder();
}
public static class Builder
{
int nationalRank = -1;
int internationalRank = -1;
String name;
public Builder nationalRank(int nationalRank)
{
this.nationalRank = nationalRank;
return this;
}
public Builder internationalRank(int internationalRank)
{
this.internationalRank = internationalRank;
return this;
}
public Builder name(String name)
{
this.name = name;
return this;
}
public Player build()
{
if (nationalRank == -1 && internationalRank = -1)
throw new IllegalStateException("both ranks haven't been initialized");
if (null == name)
throw new IllegalStateException("name hasn't been initialized");
Player result = new Player();
result.nationalRank = this.nationalRank;
result.internationalRank = this.internationalRank;
result.name = this.name;
return result;
}
}
}
Usage:
Player player = Player.builder().name("John").internationalRank(522).build();
You've got various options.
The simplest is to add factory methods like this:
public class Player
{
private int nationalRank;
private int internationalRank;
private String name;
private Player()
{
}
public static Player newNationalPlayer(String name, int nationalRank)
{
Player nationalPlayer = new Player();
nationalPlayer.name= name;
nationalPlayer.nationalRank = nationalRank;
nationalPlayer.internationalRank = 0;
return nationalPlayer;
}
public static Player newInternationalPlayer(String name, int internationalRank)
{
Player internationalPlayer = new Player();
internationalPlayer.name= name;
internationalPlayer.nationalRank = 0;
internationalPlayer.internationalRank = internationalRank;
return internationalPlayer;
}
...
}
However, this leaves an unused variable which isn't very nice. A better solution would be to add a PlayerType enum:
public enum PlayerType
{
NATIONAL,
INTERNATIONAL
}
public class Player
{
private int rank;
private String name;
private PlayerType type;
public Player(String name, PlayerType type, int rank)
{
this.name= name;
this.type = type;
this.rank = rank;
}
...
}
Which is best is down to the exact use case.
Just reverse the parameters of one of the constructors and you are good to go.... I made this answer thinking that it's an interview question....perhaps the interviewer has this in mind...
class Player
{
int nationalRank;
int internationalRank;
String name;
Player(String name, int nationalRank)
{
this.name= name;
this.nationalRank = nationalRank;
this.internationalRank=0;
}
Player( int internationalRank,String name)
{
this.name= name;
this.nationalRank = 0;
this.internationalRank=internationalRank;
}
}
As suggested by a comment, just use static factory methods. In fact, this solution goes further than that and uses a builder. You will note a clear advantage: all instance variables are now final.
public class Player
{
private final String name;
private final int nationalRank;
private final int internationalRank;
// Constructor becomes private
private Player(final Builder builder)
{
name = builder.name;
nationalRank = builder.nationalRank;
internationalRank = builder.internationalRank;
}
public static Builder withName(final String name)
{
return new Builder(name);
}
// Inner builder class
public static class Builder
{
private final String name;
private int nationalRank;
private int internationalRank;
private Builder(final String name)
{
this.name = name;
}
public Builder withNationalRank(int rank)
{
nationalRank = rank;
return this;
}
public Builder withInternationalRank(int rank)
{
internationationalRank = rank;
return this;
}
public Player build()
{
return new Player(this);
}
}
}
Usage:
Player player1 = Player.withName("foo").withNationalRank(1).build();
// etc