How to write a toString method for ArrayList? - java

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.

Related

Why do I keep getting a Null Exception Error?

I have three classes in my program. Ship.java, Cabin.java and Passenger.java. According to the program a single cabin can hold upto a maximum of 3 passengers. I'm trying to set passenger details but i keep getting this error
Cannot invoke "classes.Passenger.setFirstName(String)" because
"classes.Main.myShip[0].passenger[0]" is null at
classes.Main.main(Main.java:22)
Ship.java
public class Ship
{
public static Scanner scanner = new Scanner(System.in);
public static Cabin[] myShip = new Cabin[12];
public static void main(String[] args)
{
for (int count = 0; count < 12; count++)
{
myShip[count] = new Cabin();
}
myShip[0].passenger[0].setFirstName("a");
}
}
Cabin.java
public class Cabin
{
int cabinNumber;
Passenger[] passenger = new Passenger[3];
public Cabin()
{
}
public Cabin(int cabinNumber, Passenger[] passenger)
{
this.cabinNumber = cabinNumber;
this.passenger = passenger;
}
public void setCabinNumber(int cNumber)
{
cabinNumber = cNumber;
}
public int getCabinNumber()
{
return cabinNumber;
}
}
Passenger.java
public class Passenger
{
String firstName;
String lastName;
int expenses;
public Passenger()
{
}
//Constructors
public Passenger(String cabinFirstName, String cabinLastName, int pExpenses)
{
firstName = cabinFirstName;
lastName = cabinLastName;
expenses = pExpenses;
}
public void setFirstName(String cabinFirstName)
{
firstName = cabinFirstName;
}
public String getFirstName()
{
return firstName;
}
public void setLastName(String cabinLastName)
{
lastName = cabinLastName;
}
public String getLastName()
{
return lastName;
}
public void setExpenses(int pExpenses)
{
expenses = pExpenses;
}
public int getExpenses()
{
return expenses;
}
}
Please be kind enough to help me out.
Your model is wrong. A ship can (and does) have cabins with no occupants. You have provided no way to have unoccupied cabins. Your cabins need to be fully booked before the ship can be built!
I would consider redefining your Cabin class to be constructed empty -- which means it would have a constructor with a signature like Cabin(), and then provide a way to assign Passengers to Cabins. Maybe this would be a method in the Cabin class, like
boolean assignPassenger(Passenger p) {
... check occupancy...
... return false if full up ...
... otherwise add 'p' to the passenger array ...
... and return true ...
}
You're halfway there in that you're attempting to set the Cabins in the Ship by using a Cabin() constructor -- which is essentially an empty Cabin -- but you have not actually implemented a constructor with that signature.
What I'm getting at here is that, rather than just tweaking some Java, I think you should rethink it a bit. You'd want, I think, to be able to have unoccupied cabins and to be able to determine which cabins are occupied.

Not using the Comparable interface in the right way

Been looking for an answer to this but it seems like my problem is more specific than others.
So i have two classes and one interface. The interface is called "Comparable" and i know that the interface does have its own method, but we will get to that in a sec.
What i have is the classes called "cityMain", "City2" and the interface "Comparable"
What my program is doing right now is that it reads from a txt file with something like:
75242;Uppsala
90325;Umeå
96133;Boden
23642;Höllviken
35243;Växjö
51000;Jönköping
72211;Västerås
etc
The semicolon gets away and the integers and strings split into two.
The numbers are zip codes and well the thing next to it is just a name of some states in sweden. After reading it from the "mainCity" i am actually sorting it so that the top zip with it's name gets to be at the top, so from the least number to the largest.
Then when it gets to read it, it goes to the "City2" class and from there it just goes by every method, one zip and one state at the time.
HOWEVER: Atm i am actually calling everything from my main and NOT from my interface.
It should go like this "mainCity" --> "Comparable" --> "City2".
The program works as it is but i want it to be correct!
I have tried to go from the "Comparable" and then call it like that but it didn't work nor did it give me an error.
Note, again: That Comparable does has its own method but i have not used it due to the fact that i wouldn't know of how to apply it as it looks right now.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class cityMain {
private static BufferedReader r;
public static void main(String[] args) {
int Z = 0;
String C = null;
try {
ArrayList<City2> City = new ArrayList<City2>();
FileReader file = new FileReader("C:\\Users\\me\\Desktop\\BB.dat");
r = new BufferedReader(file);
String currLine;
while ((currLine = r.readLine()) != null) {
if (currLine.trim().length() > 0) {
String[] split = currLine.split(";");
Z = (Integer.parseInt(split[0]));
C = (split[1]);
City.add(new City2(Z, C));
}
}
Collections.sort(City, (c1, c2) -> c1.getZipCode() - c2.getZipCode());
for (int i = 0; i < City.size(); i++) {
System.out.println(City.get(i).getZipCode() + " " + City.get(i).getCityName());
}
} catch (IOException e) {
System.out.println("Erorr : " + e);
}
}
}
HERE IS A DIFFERENT CLASS:
public class City2 implements Comparable {
private int zipCode;
private String cityName;
public City2(int zipCode, String cityName) {
this.zipCode = zipCode;
this.cityName = cityName;
}
public int getZipCode() {
return zipCode;
}
public String getCityName() {
return cityName;
}
public void addAndPrint() {
}
}
HERE IS THE INTERFACE:
public interface Comparable {
public int getZipCode();
public String getCityName();
public void addAndPrint();
}
What i should get, which i already do get but not in the way that i am supposed to do it!
23642 Höllviken
35243 Växjö
51000 Jönköping
72211 Västerås
75242 Uppsala
90325 Umeå
96133 Boden
Anything would be greatly appreciated right now!
If you explicitly require to use the Comparable interface then change your City2 class to :
public class City2 implements Comparable<City2> {
private int zipCode;
private String cityName;
public City2(int zipCode, String cityName) {
this.zipCode = zipCode;
this.cityName = cityName;
}
public int getZipCode() {
return zipCode;
}
public String getCityName() {
return cityName;
}
public void addAndPrint() {
}
#Override
public int compareTo(City2 city) {
return this.getZipCode() - city.getZipCode();
}
}
Observe that :
Here we are implementing the Comparable<City2> rather than the raw
type Comparable
Overriding the compareTo() to compare zip-codes as required.
There is no need for you to explicitly create an interface
Comparable, but instead just implement the one java provides.
If you plan to use Java standard library sorting you need to use standard interfaces. You need either collection elements to implement java.lang.Comparable or a separate java.lang.Comparator object.
It would be best to delete or rename your own version of Comparator, it makes unclear which one is actually used when looking at your code because java.lang classes are imported automatically.
You have already created a java.lang.Comparator with below (c1, c2) lambda:
Collections.sort(City, (c1, c2) -> c1.getZipCode() - c2.getZipCode());
although you could have written it also as:
Collections.sort(City, Comparator.comparingInt(City2::getZipCode));
Or using List.sort:
City.sort(Comparator.comparingInt(City2::getZipCode));
Okay so...
Now it is almost 100% Complete!
But i am getting the same answer over and over again...
Ideas?
It is like the prints repeat but the last lines are actually correct....
Main class:
public class cityMain
private static BufferedReader r;
public static ArrayList<City2> City = new ArrayList<City2>();
public static void main(String[] args) {
int Z = 0;
String C = null;
try {
FileReader file = new FileReader("C:\\Users\\karwa\\Desktop\\BB.dat");
r = new BufferedReader(file);
String currLine;
while ((currLine = r.readLine()) != null) {
City.sort(Comparator.comparing(City2::getZipCode));
if (currLine.trim().length() > 0) {
String[] split = currLine.split(";");
Z = (Integer.parseInt(split[0]));
C = (split[1]);
City2 d = new City2(Z, C);
City.add(d);
d.print();
}
}
} catch (IOException e) {
System.out.println("Erorr : " + e);
}
}
Second class:
class City2 implements Comparable<City2> {
private int zipCode;
private String cityName;
public City2(int zipCode, String cityName) {
this.zipCode = zipCode;
this.cityName = cityName;
}
public int getZipCode() {
return zipCode;
}
public String getCityName() {
return cityName;
}
#Override
public int compareTo(City2 city) {
return this.getZipCode() - city.getZipCode();
}
public void print() {
for (int i = 0; i < cityMain.City.size(); i++) {
System.out.println(cityMain.City.get(i).getZipCode() + " " + cityMain.City.get(i).getCityName());
}
}
}

Can't print objects stored in HashMap?

I'm working on an assignment for my java class, and we just started learning about HashMaps and we have this assignment where we create enumerated data and store it in a hashmap to print out later. What I can seem to figure out is to be able to print the elements of the HashMap. Here is my project so far:
public class Driver <enumeration>
{
private static HashMap<String, State> stateList = new HashMap<String, State>();
public static void main(String args[]) throws IOException
{
stateList.put("1", State.CA);
stateList.put("2", State.FL);
stateList.put("3", State.ME);
stateList.put("4", State.OK);
stateList.put("5", State.TX);
for(State value : stateList.values())
{
System.out.println(value);
}
}
}
public enum State
{
CA(new StateInfo("Sacramento", 38802500)), FL(new StateInfo("Tallahassee", 19893297)),
ME(new StateInfo("Augusta", 1330089)), OK(new StateInfo("Oklahoma City", 3878051)),
TX(new StateInfo(" Austin", 26956958));
private StateInfo info;
private State(StateInfo info)
{
this.info = info;
}
public StateInfo getInfo()
{
return info;
}
public String toString()
{
return "";
}
}
public class StateInfo
{
private String capital;
private int population;
public StateInfo(String capital, int population)
{
this.capital = capital;
this.population = population;
}
public String getCapital()
{
return capital.toString();
}
public int getPopulation()
{
return population;
}
public String toString()
{
return "";
}
}
Now when I try to run the program, it just terminates without even as much as a reference number for the state objects I'm trying to print. What I think is wrong is in the StateInfo class so I tried changing some things but to no prevail. Can anyone tell me if my suspensions are correct, or am I overlooking something?
You have overridden the toString() method in the State class:
public String toString()
{
return "";
}
Therefore you get no output at all as for every value the toString() method is called in your loop:
for(State value : stateList.values())
{
System.out.println(value);
}
To be more precise: You should get 5 empty lines.
Remove the toString()method in order to use Java's default toString() implementation which returns the classname+hashCode() or make it return e.g. "Capital: " + info.getCapital().

make a global object in java

I want to make an array of objects and use it in different functions. I wrote this pseudocode
privat stock[] d;
privat stock example;
public void StockCheck(){
d =new stock[2];
d[0]= new stock("a","test1", 22);
d[1]= new stock("b","test2", 34);
}
#Override
public stock getStock(String name) throws StockCheckNotFoundException{
int i;
System.out.println("ok" + name + d.legth); // error
example = new stock("example","example",2);
return example;
}
In class test I make an instance of getStock and I call the function getStock stock.getStock();
I get a NullPointerExeption when I do d.length. d is null but I don't understand why.
Hmmmm. If that is in any way like your real code, then the problem is that your "constructor" isn't really a constructor, as you've declared it to return void, making it an ordinary method instead. Remove tbat "void" and it may fix the problem!
Perhaps this example of code will do what you need, using three classes
Test - the main test code
Stock - the implied code for Stock from your question
StockCheck - the corrected code from your question.
(Note: you may really want to use an ArrayList inside StockQuote so you can add and delete Stocks.)
Test class
package stackJavaExample;
public class Test {
public static void main(String[] args) {
String[] testNames = {"test1","test2","notThere"};
StockCheck mStockCheck = new StockCheck();
for (int i=0; i<testNames.length; i++) {
Stock result = mStockCheck.getStock(testNames[i]);
if (result == null) {
System.out.println("No stock for name: " + testNames[i]);
} else {
System.out.println("Found stock: " + result.getName() + ", " + result.getSymbol() + ", " + result.getValue());
}
}
}
}
Stock class
package stackJavaExample;
public class Stock {
private String symbol;
private String name;
private double value;
public Stock(String symbol, String name, double value) {
this.symbol = symbol;
this.name = name;
this.value = value;
}
public String getSymbol() { return symbol;}
public String getName() { return name;}
public double getValue() {return value;}
}
StockCheck class
package stackJavaExample;
public class StockCheck {
private Stock[] d;
public StockCheck() {
d = new Stock[2];
d[0] = new Stock("a","test1", 22);
d[1] = new Stock("b","test2", 34);
}
public Stock getStock(String name) {
for (int i=0; i < d.length; i++) {
if (d[i].getName().equalsIgnoreCase(name)) {
return d[i];
}
}
return null;
}
}

.equals() method to detect duplicate array elements (tried #Override)

I have a simple loop that checks for any duplicate results,
where studresults holds my results , result is the object result given to the method and r is the current object from the array.
I have been using this method successfully throughout the program although it is not working in this case even though when I debug result and r , are exactly the same does anyone know why this might be? I have tried #Override already as suggested in other answers to no avail.
I am trying to stop duplicated array elements by throwing an exception.
for(Result r : studresults)
{
if(r.equals(result))
{
return false;
}
}
EDIT OK HERE IS THE WHOLE CLASS>
package ams.model;
import java.util.ArrayList;
import java.util.Arrays;
import ams.model.exception.EnrollmentException;
public abstract class AbstractStudent implements Student {
private int studentId;
private String studentName;
private ArrayList<Course> studcourses = new ArrayList<Course>();
private ArrayList<Result> studresults = new ArrayList<Result>();
public AbstractStudent(int studentId, String studentName) {
this.studentId = studentId;
this.studentName = studentName;
}
public String getFullName() {
return studentName;
}
public int getStudentId() {
return studentId;
}
public Result[] getResults() {
Result[] res = studresults.toArray(new Result[0]);
if(res.length > 0 )
{
return res;
}
return null;
}
public boolean addResult(Result result)
{
for(Result r : studresults)
{
if(r.equals(result))
{
return false;
}
}
studresults.add(result);
return true;
}
public void enrollIntoCourse(Course c)
{
//for re-enrollment
if(studcourses.contains(c))
{
studcourses.remove(c);
studresults.clear();
}
studcourses.add(c);
}
public void withdrawFromCourse(Course c) throws EnrollmentException
{
if(studcourses.size() > 0)
{
studcourses.remove(c);
}
else
throw new EnrollmentException();
}
public Course[] getCurrentEnrolment()
{
return studcourses.toArray(new Course[0]);
}
public abstract int calculateCurrentLoad();
public int calculateCareerPoints() {
// TODO Auto-generated method stub
return 0;
}
public String toString()
{
return studentId + ":" + studentName +":" + calculateCurrentLoad();
}
}
Do you already override hashCode method in Result?
If you override equals, you have to override the hashCode method also to allow you return the same hashcode for the similar objects (objects which has the same value but actually different object instances).
I think the default implementation of hashcode will returns different value for a different object instances even though they have the same values.
Instead I converted toString and then compared and it works???
Makes me think there was something slightly unidentical before?
New method
public boolean addResult(Result r)
{
for (Result s : studresults)
{
String sr1 = s.toString();
String sr2 = r.toString();
if(sr1.equals(sr2))
{
return false;
}
}

Categories

Resources