JAVA - Issues Printing ArrayList - java

I'm currently attempting to make a lottery program through the use of a GUI. I can not figure out why the method getTicketNumbers() is not returning anything. It is simply printing [].
And so too is:
String output = "Name: " + name + "\nNumbers: " + ticketNumbers + "\n\n";
tickNumbers is outputting [] but name successfully prints out the name.
I added a System.out.print to the Ticket class in the constructor to confirm the ArrayList is being passed successfully and it is:
public Ticket(ArrayList<Integer> ticketNumbers, String name) {
this.ticketNumbers = ticketNumbers;
this.name = name;
System.out.print("Are the numbers being passed:" + ticketNumbers + "\n");
}
The method toString is successfully printing the name but again, it is not printing the ArrayList called ticketNumbers.
private void enterLottoButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (nameInput.getText().equalsIgnoreCase("")) {
JOptionPane.showMessageDialog(null, "Please Enter Your Name", "Error", JOptionPane.ERROR_MESSAGE);
} else if (ticketNumbers.size() < 4) {
JOptionPane.showMessageDialog(null, "Please Enter Four Numbers", "Error", JOptionPane.ERROR_MESSAGE);
} else {
ticketList.add(new Ticket(ticketNumbers, nameInput.getText()));
JOptionPane.showMessageDialog(null, "You Successfully Entered! \n\nName: " + nameInput.getText() + "\nNumbers: " + ticketNumbers.toString());
ticketNumbers.clear();
numbersTextField.setText("");
nameInput.setText("");
numberOfPeopleLabel.setText(" People Entered: " + ticketList.size());
}
Ticket Class:
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JOptionPane;
public class Ticket {
private String name;
private ArrayList<Integer> ticketNumbers = new ArrayList<>();
public Ticket(ArrayList<Integer> ticketNumbers, String name) {
this.ticketNumbers = ticketNumbers;
this.name = name;
System.out.print("Are the numbers being passed:" + ticketNumbers + "\n");
}
public String getName() {
return name;
}
public ArrayList<Integer> getTicketNumbers() {
return ticketNumbers;
}
public ArrayList<Integer> getSortedTicketNumbers() {
Collections.sort(ticketNumbers);
return ticketNumbers;
}
#Override
public String toString() {
String output = "Name: " + name + "\nNumbers: " + ticketNumbers + "\n\n";
return output;
}
}
If needed, code in its entirety:
http://pastebin.com/7i8VWQLk and http://pastebin.com/iRd49Nc7

ticketNumbers.clear()
This line cause the problem. As you said, during the construction of Ticket object, the data been passed in correctly in this line: ticketList.add(new Ticket(ticketNumbers, nameInput.getText()));. But you cleared them afterwards. You will need a clone of ticketList. Regardless of the best practice, you can do it inside Ticket class.
private List<Integer> clonedTicketNumbersList = new ArrayList<Integer>();
public Ticket(ArrayList<Integer> ticketNumbers, String name) {
this.ticketNumbers = ticketNumbers;
this.name = name;
for(Integer ticketNum : ticketNumbers) {
clonedTicketNumbersList.add(ticketNum );
}
System.out.print("Are the numbers being passed:" + ticketNumbers + "\n");
}
#Override
public String toString() {
String output = "Name: " + name + "\nNumbers: " + clonedTicketNumbersList + "\n\n";
return output;
}

It looks like you're copying the reference to the list, and so when you clear it in one place (or modify it) it changes/clears everywhere.
Try making a defensive copy. Like:
ArrayList<Integer> tickets = new ArrayList<>(ticketNumbers)

Related

Java inheritence and arraylist to sort [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
Hey i have a project in which by using inheritence and arraylist i have to take input from file and then show the output after sorting them year wise but in my code my array list's are empty and i am not able to figure out how to solve it.
import java.io.FileNotFoundException;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
Driver driver = new Driver();
driver.start();
}
}
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.io.*;
public class Driver {
public void start() throws FileNotFoundException{
// Initialize arraylists
ArrayList<Movie> adventure = new ArrayList<>();
ArrayList<Movie> drama = new ArrayList<>();
ArrayList<Movie> fantasy = new ArrayList<>();
ArrayList<Movie> romance = new ArrayList<>();
ArrayList<Movie> sciFi = new ArrayList<>();
ArrayList<Movie> thriller = new ArrayList<>();
ArrayList<Movie> war = new ArrayList<>();
File myObj = new File("MovieListing.txt");
Scanner myReader = new Scanner(myObj);
String directorName = myReader.nextLine();
String composerName = myReader.nextLine();
while(myReader.hasNextLine()) {
String movie = myReader.nextLine();
String[] movieInfo = movie.split(",");
String title = movieInfo[0];
int year = Integer.parseInt(movieInfo[1]);
String genre = movieInfo[2];
String rating = movieInfo[3];
Movie movie1 = new Movie(title,year,genre,rating,directorName,composerName);
//sort movies into arraylists
if (genre.equals("Adventure"))
{
adventure.add(movie1);
}
else if (genre.equals("Drama"))
{
drama.add(movie1);
}
else if (genre.equals("Fantasy"))
{
fantasy.add(movie1);
}
else if (genre.equals("Romance"))
{
romance.add(movie1);
}
else if (genre.equals("Sci Fi"))
{
sciFi.add(movie1);
}
else if (genre.equals("Thriller"))
{
thriller.add(movie1);
}
else if (genre.equals("War"))
{
war.add(movie1);
}
}
myReader.close();
System.out.print(adventure);
for(Movie movie:war) {
System.out.print(movie.getTitle());
}
// Ask the user which genre they would like to view
String genre = JOptionPane.showInputDialog("Director: " +directorName + "\n" +
"Composer: " + composerName + "\n" +
"Which genre would you like? \n" +
"1. Adventure \n" +
"2. Drama \n" +
"3. Fantasy \n" +
"4. Romance \n" +
"5. SciFi \n" +
"6. Thriller \n" +
"7. War \n" +
"Your choice: ");
// Sort the movies by year released
adventure.sort(new MovieComparator());
drama.sort(new MovieComparator());
fantasy.sort(new MovieComparator());
romance.sort(new MovieComparator());
sciFi.sort(new MovieComparator());
thriller.sort(new MovieComparator());
war.sort(new MovieComparator());
// Display the output dialog box
String output = "Director: " +directorName + "\n" +
"Composer: " +composerName + "\n" +
"Genre: " + genre + "\n" +
"Movie Title\tYear Released\tRating\n";
if (genre.equals("1")) {
for (Movie movie : adventure) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("2")) {
for (Movie movie : drama) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("3")) {
for (Movie movie : fantasy) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("4")) {
for (Movie movie : romance) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("5")) {
for (Movie movie : sciFi) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("6")) {
for (Movie movie : thriller) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
else if (genre.equals("7")) {
for (Movie movie : war) {
output += movie.getTitle() + "\t\t" + movie.getYearReleased() + "\t\t" + movie.getRating() + "\n";
}
}
JOptionPane.showMessageDialog(null, output);
}
}
public class Movie extends Director {
private String title;
private int yearReleased;
private String genre;
private String rating;
public Movie(String title, int yearReleased, String genre, String rating, String directorName, String composerName) {
super(directorName, composerName);
this.title = title;
this.yearReleased = yearReleased;
this.genre = genre;
this.rating = rating;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getYearReleased() {
return yearReleased;
}
public void setYearReleased(int yearReleased) {
this.yearReleased = yearReleased;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
}
public class Director {
private String directorName;
private String composerName;
public Director(String d, String c) {
this.directorName = d;
this.composerName = c;
}
public String getDirectorName() {
return directorName;
}
public void setDirectorName(String directorName) {
this.directorName = directorName;
}
public String getComposerName() {
return composerName;
}
public void setComposerName(String composerName) {
this.composerName = composerName;
}
}
This is the link for the file that needs to be useed in the code https://drive.google.com/file/d/1FkDSAlEv3waby-ML1dKPf3Ouk3S7O99O/view?usp=sharing
Ecpected output format:-
Director: Steven Spielberg
Composer: John Williams
Genre: Drama
Movie Title Year Released Rating
Amistad 1997 R
The Post 2017 PG-13
....
Running your code without any changes throwed an exception:
java.lang.NumberFormatException: For input string: " 1994"
The exception was reported to be caused by this statement in class Driver:
int year = Integer.parseInt(movieInfo[1]);
The reason is quite obvious: There is a leading space infront of 1994, that's why it is throwing that exception. The reason why there is a space infront of 1994 lies within the input file:
Schindler's List, 1994, War, R
The same applies for the "genre" column in the input file and that's the reason why none of the imported movies is associated to the pre-defined genres during import:
if (genre.equals("War")) {
" War" (from import) is different from "War".
You need to remove leading (and trailing) spaces during import. You could do this calling java.lang.String#trim() on item of array movieInfo or by using an appropriate regular expression whith java.lang.String#split(String):
String[] movieInfo = movie.split(",\\s*");
This will split the input line at every occurence of "comma, followed optionally by spaces", effectively removing leading spaces from the imported fields.

How to Pair Up Random Indices of an ArrayList with each other

I am currently working on a project where I read in a CSV file that contains a list of Pokemon, as well as their traits. I am trying to run a battle simulator that randomly pairs up these Pokemon with each other and compares their combatScore, which is a result of a simple calculation using their traits such as speed, attack, defense, etc. I read in all of the Pokemon from the CSV file into an ArrayList of type Pokemon. Now, I want to randomly pair them up with each other and compare their combatScore; whoever has the higher score moves on to the next round, and the loser is placed into another ArrayList of defeated Pokemon. However, I do not know how to randomly pair up the Pokemon. Here is my code of the main class so far:
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
public class assign1 {
public static void main(String[] args) throws IOException {
String csvFile = args[0]; //path to CSV file
String writeFile = args[1]; //name of output file that contains list of Pokemon and their traits
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
ArrayList<Pokemon> population = new ArrayList<Pokemon>();
FileWriter fileWriter = new FileWriter(writeFile);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
try {
br = new BufferedReader(new FileReader(csvFile));
String headerLine = br.readLine(); // used to read first line of CSV file that contains headers
while ((line = br.readLine()) != null) {
Pokemon creature = new Pokemon();
// use comma as separator
String[] pokemon = line.split(cvsSplitBy);
creature.setId(pokemon[0]);
creature.setName(pokemon[1]);
creature.setType1(pokemon[2]);
creature.setType2(pokemon[3]);
creature.setTotal(pokemon[4]);
creature.setHp(Integer.parseInt(pokemon[5]));
creature.setAttack(Integer.parseInt(pokemon[6]));
creature.setDefense(Integer.parseInt(pokemon[7]));
creature.setSpAtk(Integer.parseInt(pokemon[8]));
creature.setSpDef(Integer.parseInt(pokemon[9]));
creature.setSpeed(Integer.parseInt(pokemon[10]));
creature.setGeneration(Integer.parseInt(pokemon[11]));
creature.setLegendary(Boolean.parseBoolean(pokemon[12]));
creature.getCombatScore();
// Adds individual Pokemon to the population ArrayList
population.add(creature);
// Writes to pokemon.txt the list of creatures
bufferedWriter.write(creature.getId() + ". "
+ "Name: " + creature.getName() + ": "
+ "Type 1: " + creature.getType1() + ", "
+ "Type 2: " + creature.getType2() + ", "
+ "Total: " + creature.getTotal() + ", "
+ "HP: " + creature.getHp() + ", "
+ "Attack: " + creature.getAttack() + ", "
+ "Defense: " + creature.getDefense() + ", "
+ "Special Attack: " + creature.getSpAtk() + ", "
+ "Special Defense: " + creature.getSpDef() + ", "
+ "Speed: " + creature.getSpeed() + ", "
+ "Generation: " + creature.getGeneration() + ", "
+ "Legendary? " + creature.isLegendary() + ", "
+ "Score: " + creature.getCombatScore());
bufferedWriter.newLine();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (br != null) {
try {
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
bufferedWriter.close();
}
}
And here is the code for my Pokemon class:
public class Pokemon {
String id;
String name;
String type1;
String type2;
String total;
int hp;
int attack;
int defense;
int spAtk;
int spDef;
int speed;
int generation;
boolean legendary;
public Pokemon() {}
public String getId () {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType1() {
return type1;
}
public void setType1(String type1) {
this.type1 = type1;
}
public String getType2() {
return type2;
}
public void setType2(String type2) {
this.type2 = type2;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public int getSpAtk() {
return spAtk;
}
public void setSpAtk(int spAtk) {
this.spAtk = spAtk;
}
public int getSpDef() {
return spDef;
}
public void setSpDef(int spDef) {
this.spDef = spDef;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getGeneration() {
return generation;
}
public void setGeneration(int generation) {
this.generation = generation;
}
public boolean isLegendary() {
return legendary;
}
public void setLegendary(boolean legendary) {
this.legendary = legendary;
}
public int getCombatScore() {
return (speed/2) * (attack + (spAtk/2)) + (defense + (spDef/2));
}
#Override
public String toString() {
return "Name: " + this.getName()
+ ", Type 1: " + this.getType1()
+ ", Type 2: " + this.getType2()
+ ", Total: " + this.getTotal()
+ ", HP: " + this.getHp()
+ ", Attack: " + this.getAttack()
+ ", Defense: " + this.getDefense()
+ ", Sp. Attack: " + this.getSpAtk()
+ ", Sp. Defense: " + this.getSpDef()
+ ", Generation: " + this.getGeneration()
+ ", Legnedary: " + this.isLegendary()
+ ", Score: " + this.getCombatScore();
}
}
I only want to compare their combatScore values to each other. Any help/suggestions would be much appreciated.
What come to my mind is this. You pick one random item (pokemon) from array list. Remove it from array list. Then you pick one random item again and remove it. Now you have a pair of items. Repeat above step for remaining items in array list until no more items available.
Or you can shuffle whole array list first and then pick item i and item i+1 as pair for i=0,2,4,6,...
Collections.shuffle(pokemonsArrayList);
for (int i=0; i< pokemonsArrayList.size(); i+=2) {
pokemon1 = pokemonsArrayList.get(i);
pokemon2 = pokemonsArrayList.get(i+1);
}
Just make sure that number of elements in ArrayList is even. Otherwise code above will throw exception index out of bound
Since every element in an ArrayList has an index, you can just get a random element from it by calling
Pokemon pokemon1;
Pokemon pokemon2;
pokemon1 = arrayList.get(Math.random()*arrayList.size());
do {
pokemon2 = arrayList.get(Math.random()*arrayList.size());
} while(pokemon1.getId() == pokemon2.getId());
then compare the Pokémon you got out of List1 with the one you got from List2.
You can then of course remove the Pokémon from the List if you wish.
Hope that helps you out!

Null Pointer Exception Error, not sure why

So I had to create a method that separated input string into first/middle/last names, counted the number of "students" created, etc, and then I had to create a class that tested those methods.
public void setName(String newName)
{
String[] nameInput = newName.split(" ");
if(nameInput.length == 0)
{
System.out.println("Error, please enter at least two names.");
newName = null;
}
else if(nameInput.length == 1)
{
firstName = nameInput[0];
middleName = "";
lastName = nameInput[1];
newName = firstName + lastName;
}
else if(nameInput.length == 2)
{
firstName = nameInput[0];
middleName = nameInput[1];
lastName = nameInput[2];
newName = firstName + middleName + lastName;
}
else
{
System.out.println("Error! You can only enter up to three names.");
}
}
public String getName()
{
if (middleName == null)
{
return firstName + " " + lastName;
}
else
return firstName + " " + middleName + " " + lastName;
}
public String getId()
{
return identifier = generateID();
}
#Override
public String toString()
{
return getName() + "\n" + "(" + generateID() + ")";
}
private String generateID()
{
return UUID.randomUUID().toString();
}
and this is the way I am testing the code:
public static void testStudent()
{
System.out.println("Trying to create testStudent1 with a single name...");
testStudent1 = new Student("A");
System.out.println("testStudent1.toString() is " + testStudent1.toString());
System.out.println("testStudent1.getFirstName() is " + testStudent1.getFirstName());
System.out.println("testStudent1.getMiddleName() is " + testStudent1.getMiddleName());
System.out.println("testStudent1.getLastName() is " + testStudent1.getLastName());
System.out.println("Trying to create testStudent2 with two names...");
testStudent1 = new Student("A B");
System.out.println("testStudent2.toString() is " + testStudent2.toString());
System.out.println("testStudent2.getFirstName() is " + testStudent2.getFirstName());
System.out.println("testStudent2.getMiddleName() is " + testStudent2.getMiddleName());
System.out.println("testStudent2.getLastName() is " + testStudent2.getLastName());
System.out.println("Trying to create testStudent3 with three names...");
testStudent1 = new Student("A B C");
System.out.println("testStudent3.toString() is " + testStudent3.toString());
System.out.println("testStudent3.getFirstName() is " + testStudent3.getFirstName());
System.out.println("testStudent3.getMiddleName() is " + testStudent3.getMiddleName());
System.out.println("testStudent3.getLastName() is " + testStudent3.getLastName());
}
I keep running into a null pointer exceptions when it tests toString for a student with 2 names, and I have no clue why.
Edit: The issue is with the testStudent variable in the testStudent() method.
System.out.println("Trying to create testStudent1 with a single name...");
testStudent1 = new Student("A");
System.out.println("testStudent1.toString() is " + testStudent1.toString());
System.out.println("testStudent1.getFirstName() is " + testStudent1.getFirstName());
System.out.println("testStudent1.getMiddleName() is " + testStudent1.getMiddleName());
System.out.println("testStudent1.getLastName() is " + testStudent1.getLastName());
System.out.println("Trying to create testStudent2 with two names...");
Student testStudent2 = new Student("A B");
System.out.println("testStudent2.toString() is " + testStudent2.toString());
System.out.println("testStudent2.getFirstName() is " + testStudent2.getFirstName());
System.out.println("testStudent2.getMiddleName() is " + testStudent2.getMiddleName());
System.out.println("testStudent2.getLastName() is " + testStudent2.getLastName());
System.out.println("Trying to create testStudent3 with three names...");
Student testStudent3 = new Student("A B C");
System.out.println("testStudent3.toString() is " + testStudent3.toString());
System.out.println("testStudent3.getFirstName() is " + testStudent3.getFirstName());
System.out.println("testStudent3.getMiddleName() is " + testStudent3.getMiddleName());
System.out.println("testStudent3.getLastName() is " + testStudent3.getLastName());
Since you are re-using the testStudent1 variable to create a new Object of Student class and not using them to invoke getter functions, it will throw an NPE for testStudent2 and testStudent3 variables.
Answer for old issue: The issue is with your while statement. It will never stop.
You can just find out the count by doing nameInput.length for the String array.
It should be like this:
String[] nameInput = newName.split(" ");
if (nameInput.length == 1)
{
System.out.println("Error, please enter at least two names.");
newName = null;
}
else if (nameInput.length == 2)
{
...
}
else if (nameInput.length == 3)
{
...
}
else
{
...
}
You could use StringTokenizer class to help you with this.
import java.util.StringTokenizer
StringTokenizer test = new StringTokenizer("An example string");
while (test.hasMoreTokens()) {
System.out.println(test.nextToken());
}
Output:
An
example
string.
The countTokens() method can provide how many tokens a string will provide prior processing. That way you will know if you have a middle name or not.
please check trim() method
public static void getName(String newName) {
newName = newName.trim();
String fullName = null;
String[] nameInput = newName.split(" ");
switch (nameInput.length) {
case 2:
fullName = mergeName(nameInput[0], "", nameInput[1]);
break;
case 3:
fullName = mergeName(nameInput[0], nameInput[1], nameInput[2]);
break;
default:
System.out.println("Error, please enter at least two names.");
break;
}
System.out.println(fullName);
}
public static String mergeName(String firstName, String middleName,
String lastName) {
String name = firstName+" " + middleName+" " + lastName;
return name;
}

How to leave out a null value in a loop in Java

Here's my Java Code:
public class DVD {
public static void main(String[] args) {
DVD newdvd1 = new DVD();
newdvd1.setPlayit("The song is playing \n");
newdvd1.setArtist("Eva Cassidy");
newdvd1.setTitle("Songbird");
newdvd1.setGenre("Blues");
System.out.println(newdvd1.getPlayit());
System.out.println(newdvd1);
DVD newdvd2 = new DVD();
newdvd2.setPlayit("The next song is playing \n");
newdvd2.setArtist("an unknown artist");
newdvd2.setTitle("new song");
System.out.println(newdvd2.getPlayit());
System.out.println(newdvd2);
}
private String artist;
private String title;
private String genre;
private String playit;
public String getPlayit() {
return playit;
}
public void setPlayit(String playit) {
this.playit = playit;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String toString () {
return ("The artist is called " + artist +
" who is a "+ genre + " singer" +
" and this song is called " + title + ".\n");
}
}
what it outputs is:
The song is playing
The artist is called Eva Cassidy who is a Blues singer and this song is called Songbird.
The next song is playing
The artist is called an unknown artist who is a null singer and this song is called new song.
What i'm asking is, in the second song, how do i leave out 'null singer' as I don't want to display the second songs genre?
Use the ?: (ternary) operator. See JLS specs, for example.
return ("The artist" +
(artist == null ? "" : " is called " + artist) +
(genre == null ? "" : " who is a "+ genre + " singer") +
(title == null ? "" : " and this song is called " + title) +
".\n");
If the given property is not null, you print the relevant text, otherwise simply print nothing.
You can also define sensible default values like:
(artist == null ? " is unknown" : "is called " + artist) +
You can try this.
public String toString() {
StringBuilder builder = new StringBuilder();
if (artist != null && !artist.isEmpty()) {
builder.append("The artist is called : " + artist);
}
if (genre != null && !genre.isEmpty()) {
builder.append(" who is a " + genre + " singer");
}
if (title != null && !title.isEmpty()) {
builder.append(" and this song is called " + title + ".\n");
}
return (builder.toString());
}
If you want the solution to be generic for then modify your toString method as:
public String toString () {
String returnString = "The artist is called " + artist ;
if(genre !=null && !"".equals(genre.trim())) {
returnString += " who is a "+ genre + " singer" +;
}
returnString += " and this song is called " + title + ".\n";
return returnString;
}
You can add more null checks if required for artist and title as well.
You should override toString() using some condition
public String toString () {
if(genre!=null){
return ("The artist is called " + artist +
" who is a "+ genre + " singer" +
" and this song is called " + title + ".\n");
}else{
return ("The artist is called " + artist +
" and this song is called " + title + ".\n");
}
}
If its just about the singer, you could do the following:
public String toString() {
String temp = "The artist is called " + artist";
if(singer != null){ //checks if the object "singer" is not null
temp+=" who is a " + genre + " singer";
}
temp+="and this song is called "+ title + ".\n";
return temp;
}
You can insert a null check to skip this part. Anyway you should use a StringBuffer for that otherwise you are creating many String objects and make the GC angry. Every + creates a new String Object, so with a StringBuffer you only create one String at the end.
public String toString ()
{
StringBuffer buffer = new StringBuffer("The artist is called ");
buffer.append(artist);
if(genre != null)
{
buffer.append(" who is a ");
buffer.append(genre);
buffer.append(" singer");
}
buffer.append(" and this song is called ");
buffer.append(title);
buffer.append(".\n");
return buffer.toString();
}

OOP in java - creating objects

OK guys, up till now (and since I'm a beginner) I was programming Java based on procedural programming and it was nice and all but It's time to use Java like-a-boss.
I'm learning the OOP concept now while writing some code as practice.
What I dont understand is that if I create a few objects this way:
Contact first = new Contact(25, "Yosi", "Male");
System.out.println("Age of contact " + first.toString() + " is - "
+ first.getAge() + " " + first.getName());
Contact second = new Contact(22, "lisa", "Femal");
System.out.println("Age of contact " + second.toString() + " is - "
+ second.getAge() + " " + second.getName());
Contact third = new Contact(34, "Adam", "Male");
System.out.println("Age of contact " + third.toString() + " is - "
+ third.getAge() + " " + third.getName());
The result will be:
Age of contact Contact#173f7175 is - 25 Yosi
Age of contact Contact#4631c43f is - 22 lisa
Age of contact Contact#6d4b2819 is - 34 Adam
But if I then try to print the first contact again, it will get the values of the last object created. I mean, for this code:
Contact first = new Contact(25, "Yosi", "Male");
System.out.println("Age of contact " + first.toString() + " is - "
+ first.getAge() + " " + first.getName());
Contact second = new Contact(22, "lisa", "Femal");
System.out.println("Age of contact " + second.toString() + " is - "
+ second.getAge() + " " + second.getName());
Contact third = new Contact(34, "Adam", "Male");
System.out.println("Age of contact " + third.toString() + " is - "
+ third.getAge() + " " + third.getName());
System.out.println("Age of contact " + first.toString() + " is - "
+ first.getAge() + " " + first.getName());
the result will be:
Age of contact Contact#173f7175 is - 25 Yosi
Age of contact Contact#4631c43f is - 22 lisa
Age of contact Contact#6d4b2819 is - 34 Adam
Age of contact Contact#173f7175 is - 34 Adam
I've added up the object string representation so you can see the different objects.
I thought I was creating a new object and each object has it's own instance values?
could you guys explain to me?
This is the contacts class:
public class Contact {
private static int age = 0;
private static String name = "Unknown";
private static String gender = "Male";
public Contact(int a, String n, String g) {
age = a;
name = n;
gender = g;
}
public Contact() {
}
public static int getAge() {
return age;
}
public static String getName() {
return name;
}
public static String getGender() {
return gender;
}
public static void setAge(int a) {
age = a;
}
public static void setName(String n) {
name = n;
}
public static void setGender(String g) {
gender = g;
}
}
Please note that if I remove static qualifier I get errors saying "cannot make a static referance to the non static field"
Remove the static qualifier from your instance variables and/or methods (age, getAge, name, getName).
This can occur if you mistakenly use a static variable:
class Stat {
static String name;
Stat(String n) {
name = n;
}
}
In the example class above, all instances will share the same value for name.
Use non-static variables for instance members:
class Stat {
String name;
Stat(String n) {
name = n;
}
}
Well, Yosi.Static qualifiers tie your fields(and methods) to your class not to your object and each Object of your Class(Contact) share the same value.
Whenever you instantiate it by New, this value gets updated. So when you print fourth time the value it has is what you update it in third time. That'y its printing like that.
As I see you code, if you remove static from everywhere, your code will behave as you desire.

Categories

Resources