Java printing Class objects in ArrayList - java

Sailor class
public class Sailor {
private String name;
private String email;
public Sailor(String name, String email) {
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Crew class
import java.util.ArrayList;
public class Crew {
private ArrayList<Sailor> sailorList = new ArrayList<>();
public Crew() {
}
public void addCrewMember(Sailor sailor) {
sailorList.add(sailor);
}
public String toString() {
String str = "";
for(int i = 0; i < sailorList.size(); i++) {
str = sailorList.get(i).getName() + sailorList.get(i).getEmail();
}
return str;
}
}
Main program
public class ObjectsSailorProgram {
public static void main(String[] args) {
Sailor firstSailor = new Sailor("Frank", "frank#mail.com");
Sailor secondSailor = new Sailor("Susan", "susan#mail.com");
Sailor thirdSailor = new Sailor("John", "john#sailors.com");
Sailor fourthSailor = new Sailor("Ann", "ann#sailors.com");
Crew firstCrew = new Crew();
Crew secondCrew = new Crew();
firstCrew.addCrewMember(firstSailor);
firstCrew.addCrewMember(secondSailor);
firstCrew.addCrewMember(fourthSailor);
secondCrew.addCrewMember(thirdSailor);
secondCrew.addCrewMember(secondSailor);
System.out.println("=== First crew ===\n" + firstCrew);
System.out.println("=== Second crew ===\n" + secondCrew);
secondSailor.setEmail("Susan#sailors.com");
System.out.println("=== Second crew ===\n" + secondCrew);
}
}
I am having trouble printing the crews and I'm not sure if the addCrewMember is correct.
I've tried reading other similar posts but i haven't been able to use the solutions here. So i need help with the addCrewMember and toString methods

You aren't setting the variables neither in constructor nor by calling setters in your main.
You can change the constructor as below:
public Sailor(String name, String email) {
this.name = name;
this.email = email;
}
In your toString() method, you're overwriting the str. Use StringBuilder to append strings into the resulting string. You can modify your toString() method as follows:
public String toString() {
StringBuilder str = new StringBuilder();
for(int i = 0; i < sailorList.size(); i++) {
str.append(i+1)
.append(". ")
.append(sailorList.get(i).getName())
.append(" ")
.append(sailorList.get(i).getEmail())
.append("\n");
}
return str.toString();
}
And your program will give the output:
=== First crew ===
1. Frank frank#mail.com
2. Susan susan#mail.com
3. Ann ann#sailors.com
=== Second crew ===
1. John john#sailors.com
2. Susan susan#mail.com
=== Second crew ===
1. John john#sailors.com
2. Susan Susan#sailors.com

0> sailor's constructor is wrong-> you're not initializing the data
public Sailor(String name, String email) {
setEmail(email); //or this.email=email;
this.name=name; //you may make a setter also for this
}
1> private ArrayList<Sailor> sailorList = new ArrayList<Sailor>();
2> the to-string is also wrong: it prints just the last sailor, use += instead of =
str +=" "+ sailorList.get(i).getName() + sailorList.get(i).getEmail();
This is just personal taste: I prefer "for-each" syntax.
for(Sailor s: sailorList){
out += s.getName()+" "+s.getEmail();
}

As others have noted, you are not assigning the values in your Sailor constructor so do that. You should also add any missing get/set methods.
public Sailor(String name, String email) {
this.name = name;
this.email = email;
}
The addCrewMember(Sailor) method in Crew looks correct but your toString() method is flawed.
You are trying to build a String but you are re-assigning it on each iteration rather then concatenating elements on each iteration.
Except in very simple cases, you should avoid String concatenation when compose Strings.
The code is pushing all of the elements together with no separation which means you will have an unreadable blob of characters (e.g. bobsmithbsmith#boat.comsamsmithssmith#boat.com)
I would suggest that you write a toString() in Sailor class. This example separates the elements of Sailor by commas and wraps the entire entity in curly braces (e.g. "{Sam Smith, ssmith#boat.com}"). Note the use of String.format(..) rather than concatenation.
public class Sailor {
... stuff ...
#Override public String toString() {
return String.format("{%s, %s}", name, email);
}
}
The Crew.toString() method can employ this to compose its String. The following makes use of the StringJoiner class to compose a comma-separated list of elements wrapped in square braces to represent the crew members (e.g. "[{Al Almond, aalmond#boat.com},{Bob Bobson, bbobson#boat.com}]");
public class Crew {
... stuff ...
#Override public String toString() {
StringJoiner sj = new StringJoiner(",", "[", "]");
for (Sailor s : sailorList) {
sj.add(s.toString()); // Sailor.toString() is explicitly invoked here but you could remove that call and it should still be invoked implicitly
}
return sj.toString();
}
}

Related

Set and display name and email Java objects classes

I have this java class assignment, it inputs crew members and display their info, I've done other similar cases, but not sure how to construct this one.
I'm to create two classes, Sailor and CrewMember that works with this main method-
import java.util.ArrayList;
public class SailorProgram {
public static void main(String[] args) {
Sailor firstSailor = new Sailor("Jimmy", "jimmy#mail.com");
Sailor secondSailor = new Sailor("Rose", "rose#mail.com");
Sailor thirdSailor = new Sailor("James", "james#sailors.com");
CrewMember firstCrew = new CrewMember();
CrewMember secondCrew = new CrewMember();
firstCrew.addCrewMember(firstSailor);
firstCrew.addCrewMember(secondSailor);
secondCrew.addCrewMember(thirdSailor);
secondCrew.addCrewMember(secondSailor);
System.out.println(" First crew \n" + firstCrew);
System.out.println(" Second crew \n" + secondCrew);
secondSailor.setEmail("Rose#sailors.com");
System.out.println(" Second crew \n" + secondCrew);
}
}
then prints out
First crew
Jimmy (jimmy#mail.com)
Rose (rose#mail.com)
Second crew
James (james#sailors.com)
Rose (rose#mail.com)
Second crew
James (james#sailors.com)
Rose (rose#sailors.com)
thanks!
addCrewMember() is the key method we want to know. If you give the Sailor reference to the secondCrew class,the output will change.
public class Sailor {
private String name;
private String email;
public Sailor(String name, String email) {
this.name = name;
this.email = email;
}
#Override
public String toString() {return name + " " + "(" + email + ")";}
}
If the CrewMember.class Like This below
import java.util.ArrayList;
public class CrewMember {
private final ArrayList<Sailor> sailors = new ArrayList<>();
public void addCrewMember(Sailor s) { //add sailors with this
sailors.add(s);
}
#Override
public String toString() { return sailors.toString(); }
}
And run your main method in your question
thr output is this:
First crew
[Jimmy (jimmy#mail.com), Rose (rose#mail.com)]
Second crew
[James (james#sailors.com), Rose (rose#mail.com)]
Second crew
[James (james#sailors.com), Rose (Rose#sailors.com)]
Rose#sailors.com is change! because the ArrayList sailors save the reference of the Rose Sailor
The question isn't exactly clear but I will make some assumptions. First, your CrewMember class holds sailors, so a more appropriate name would be Crew. The way you can implement this is with an ArrayList<Sailor> for example.
class Crew {
private final ArrayList<Sailor> sailors = new ArrayList<>();
//other things, like constuctor here, if needed
public void addCrewMember(Sailor s) { //add sailors with this
sailors.add(s);
}
}
Then your Sailor class is very simple.
class Sailor {
private String name;
private String email;
public Sailor(String name, String email) {
this.name = name; this.email = email;
}
//other methods, like getters here
}
Edit: I noticed you need to print the objects as well. For this you can use the Object class' toString method. An example for your Sailor class:
#Override
public String toString() {
return name + ", " + email;
}
Using System.out.println(sailor1) will invoke this method on sailor1.

how can I return a String?

package book1;
import java.util.ArrayList;
public abstract class Book {
public String Book (String name, String ref_num, int owned_copies, int loaned_copies ){
return;
}
}
class Fiction extends Book{
public Fiction(String name, String ref_num, int owned_copies, String author) {
}
}
at the moment when i input values into the variable arguments and call them with this :
public static class BookTest {
public static void main(String[] args) {
ArrayList<Book> library = new ArrayList<Book>();
library.add(new Fiction("The Saga of An Aga","F001",3,"A.Stove"));
library.add(new Fiction("Dangerous Cliffs","F002",4,"Eileen Dover"));
for (Book b: library) System.out.println(b);
System.out.println();
}
}
i get a return value of this:
book1.Fiction#15db9742
book1.Fiction#6d06d69c
book1.NonFiction#7852e922
book1.ReferenceBook#4e25154f
how can i convert the classes to return a string value instead of the object value? I need to do this without changing BookTest class. I know i need to use to string to convert the values. but i don't know how to catch the return value with it. could someone please point me in the right direction on how to convert this output into a string value?
You need to overwrite the toString() Method of your Book class. In this class you can generate a String however you like. Example:
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.author).append(": ").append(this.title);
return sb.toString();
}
You need to override the toString() method in your Book or Fiction class. The method is actually declared in the Object class, which all classes inherit from.
#Override
public String toString(){
return ""; // Replace this String with the variables or String literals that you want to return and print.
}
This method is called by System.out.println() and System.out.print() when they receive an object in the parameter (as opposed to a primitive, such as int and float).
To reference the variables in the method, you'll need to declare them in the class and store them via the class's constructor.
For example:
public abstract class Book {
private String name;
private String reference;
private int ownedCopies;
private int loanedCopies;
public Book (String name, String reference, int ownedCopies, int loanedCopies) {
this.name = name;
this.reference = reference;
this.ownedCopies = ownedCopies;
this.loanedCopies = loanedCopies;
}
#Override
public String toString(){
return name + ", Ref:" + reference + ", OwnedCopies: " + ownedCopies + ", LoanedCopies: " + loanedCopies; // Replace this String with the variables or String literals that you want to return and print.
}
}
The classes you have defined, don't store any values. It is in other words useful to construct a new book. You need to provide fields:
public abstract class Book {
private String name;
private String ref_num;
private int owned_copies;
private int loaned_copies;
public String Book (String name, String ref_num, int owned_copies, int loaned_copies) {
this.name = name;
this.ref_num = ref_num;
this.owned_copies = owned_copies;
this.loaned_copies = loaned_copies;
}
public String getName () {
return name;
}
//other getters
}
Now an object is basically a set of fields. If you want to print something, you can access and print one of these fields, for instance:
for (Book b: library) System.out.println(b.getName());
In Java, you can also provide a default way to print an object by overriding the toString method:
#Override
public String toString () {
return ref_num+" "+name;
}
in the Book class.
Need to give your object Book a ToString() override.
http://www.javapractices.com/topic/TopicAction.do?Id=55
Example:
#Override public String toString()
{
return name;
}
Where name, is a string in the Class.
I am hoping that you have assigned the passed arguments to certain attributes of the classes. Now, once you are done with that, you can override the toString() method in Book to return your customized string for printing.

Java - Using an object inside an object

I am working on a project ( I had a problem yesterday and so many people helped me!) so I decided to ask for help again.
My code has 3 classes. ProjectMain,Students,Classroom. I created an array of Classroom objects. Right now I have 3 Classroom objects. But I have to assign student objects to these Classroom objects. For example : classarray[0] is an object from Classroom class and studentobject.get(0) , studentobject.get(1) ... will be students objects inside classarray[0] object. But I have failed on this while coding. Here are my classes :
public class Classroom
{
private String classname;
private String word[] = null;
protected ArrayList<Students> studentobject = new ArrayList<Students>(10);
public String[] getWord()
{
return word;
}
public void setWord(String[] word)
{
this.word = word;
}
public ArrayList<Students> getStudentobject()
{
return studentobject;
}
public void setStudentobject(ArrayList<Students> studentobject)
{
this.studentobject = studentobject;
}
public String getClassname()
{
return classname;
}
public void setClassname(String classname)
{
this.classname = classname;
}
public void classroomreader(String filename)
{
// This method gets the name of Classroom
File text = new File("C:/Users/Lab/Desktop/classlists/" + filename
+ ".txt");
Scanner scan;
try
{
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t");
line = scan.nextLine();
word = line.split("\t");
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
}
}
This is my student class :
public class Students extends Classroom
{
private String name,id;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
And my main class :
public class ProjectMain
{
public static void main(String[] args)
{
Classroom[] classarray = new Classroom[3];
//I got 3 Classroom objects here
classarray[0]=new Classroom();
classarray[1]=new Classroom();
classarray[2]=new Classroom();
classarray[0].classroomreader("class1");
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
//The problem is in here. When my code comes to the line above,
// at java.util.ArrayList.rangeCheck(Unknown Source) error comes out.
// I tried to get first object in studentobject Arraylist, and tried to set it's name
// to the variable which my text reader reads.
How can I write what I have in my mind?
Your classroomreader method reads the file but don't do much of it... maybe you want to create some instance of Students within it.
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t"); // won't be used
line = scan.nextLine();
word = line.split("\t"); // erased here
There you only have the last line (split) of the file in word attribute.
When creating Classroom instance studentobject list is created empty and it stays that way so you can't access first (or any) object in it.
To populate your list you may add to Classroom method like this:
public void addStudent(Student s)
{
studentobject.add(s);
}
classroom contains the following field declaration
String word[] = null;
the main class, incl the classroomreader does not set a value to this field. Yet you are going to invoke
classarray[0].getWord()[1]
which then must fail.
tip: don't use expressions like this, which can be found in your main class (at least not in early stages of development, or learning)
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
resolve into variables and several steps. Compilers are smart enough to produce the same code if the context is not disturbed, ie the long expression is resolved into a single block.
Never forget that the purpose of programming languages is to make programs readable for humans. :) Code with abbreviations or "tricks" simply shows some philodoxical attitude (imho)

How can I print from this object? Java

I need to print the first name, last name, and salary from two employee objects but I keep getting a cannot find symbol error. What would I do to fix this?
Here is the constructor class:
public class Employee
{
private String firstName;
private String lastName;
private double monthlySalary;
public Employee( String firstName1, String lastName1, double monthlySalary1) {
setfirstName(firstName1);
setlastName(lastName1);
setmonthlySalary(monthlySalary1);
}
String getfirstName() {
return firstName;
}
String getlastName() {
return lastName;
}
double getmonthlySalary() {
return monthlySalary;
}
public void setfirstName (String firstName1) {
firstName = firstName1;
}
public void setlastName (String lastName1) {
lastName = lastName1;
}
public void setmonthlySalary (double monthlySalary1) {
monthlySalary = ( monthlySalary1 >= 0 ? monthlySalary1 : 0);
}
}
And here is what I have so far to print the objects:
public class EmployeeTest {
public static void main(String[] args) {
Employee a = new Employee("John", "Smith", 10000);
Employee b = new Employee("Jane", "Smith", 11000);
System.out.print(a.firstName1);
}
}
I need to be able to have it print out something along the lines of "Name: Salary:" But I am clueless as to how to make this work. Any help would be greatly appreciated.
In your employee class, you need to override the toString() method.
You can try something like:
#Override
public String toString()
{
System.out.println("Name: "+name+"Salary: "+salary);
}
Then for each of your employees, when you want to print them, just call
System.out.println(employee);
You cant print out firstName (or firstName1, because that doesnt exist in your class), because its marked as private. You should do something like this:
System.out.print(a.getfirstName())
firstName is private, which means that it cannot be seen outside of the object/class it resides in. I suggest you try overriding the toString() method on your Employee class. That method would have access to all the private members of Employee.
Alternately, you could use getfirstName() to return the first name.
Also, this may be a typo, but there is no firstName1 in Employee - it is firstName.

How to use the toString method in Java?

Can anybody explain to me the concept of the toString() method, defined in the Object class? How is it used, and what is its purpose?
From the Object.toString docs:
Returns a string representation of the
object. In general, the toString
method returns a string that
"textually represents" this object.
The result should be a concise but
informative representation that is
easy for a person to read. It is
recommended that all subclasses
override this method.
The toString method for class Object
returns a string consisting of the
name of the class of which the object
is an instance, the at-sign character
`#', and the unsigned hexadecimal
representation of the hash code of the
object. In other words, this method
returns a string equal to the value
of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
Example:
String[] mystr ={"a","b","c"};
System.out.println("mystr.toString: " + mystr.toString());
output:- mystr.toString: [Ljava.lang.String;#13aaa14a
Use of the String.toString:
Whenever you require to explore the constructor called value in the String form, you can simply use String.toString...
for an example...
package pack1;
import java.util.*;
class Bank {
String n;
String add;
int an;
int bal;
int dep;
public Bank(String n, String add, int an, int bal) {
this.add = add;
this.bal = bal;
this.an = an;
this.n = n;
}
public String toString() {
return "Name of the customer.:" + this.n + ",, "
+ "Address of the customer.:" + this.add + ",, " + "A/c no..:"
+ this.an + ",, " + "Balance in A/c..:" + this.bal;
}
}
public class Demo2 {
public static void main(String[] args) {
List<Bank> l = new LinkedList<Bank>();
Bank b1 = new Bank("naseem1", "Darbhanga,bihar", 123, 1000);
Bank b2 = new Bank("naseem2", "patna,bihar", 124, 1500);
Bank b3 = new Bank("naseem3", "madhubani,bihar", 125, 1600);
Bank b4 = new Bank("naseem4", "samastipur,bihar", 126, 1700);
Bank b5 = new Bank("naseem5", "muzafferpur,bihar", 127, 1800);
l.add(b1);
l.add(b2);
l.add(b3);
l.add(b4);
l.add(b5);
Iterator<Bank> i = l.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
}
}
... copy this program into your Eclipse, and run it... you will get the ideas about String.toString...
The toString() method returns a textual representation of an object. A basic implementation is already included in java.lang.Object and so because all objects inherit from java.lang.Object it is guaranteed that every object in Java has this method.
Overriding the method is always a good idea, especially when it comes to debugging, because debuggers often show objects by the result of the toString() method. So use a meaningful implementation but use it for technical purposes. The application logic should use getters:
public class Contact {
private String firstName;
private String lastName;
public Contact (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
public String getContact() {
return firstName + " " + lastName;
}
#Override
public String toString() {
return "["+getContact()+"]";
}
}
It may optionally have uses within the context of an application but far more often it is used for debugging purposes. For example, when you hit a breakpoint in an IDE, it's far easier to read a meaningful toString() of objects than it is to inspect their members.
There is no set requirement for what a toString() method should do. By convention, most often it will tell you the name of the class and the value of pertinent data members. More often than not, toString() methods are auto-generated in IDEs.
Relying on particular output from a toString() method or parsing it within a program is a bad idea. Whatever you do, don't go down that route.
toString() returns a string/textual representation of the object.
Commonly used for diagnostic purposes like debugging, logging etc., the toString() method is used to read meaningful details about the object.
It is automatically invoked when the object is passed to println, print, printf, String.format(), assert or the string concatenation operator.
The default implementation of toString() in class Object returns a string consisting of the class name of this object followed by # sign and the unsigned hexadecimal representation of the hash code of this object using the following logic,
getClass().getName() + "#" + Integer.toHexString(hashCode())
For example, the following
public final class Coordinates {
private final double x;
private final double y;
public Coordinates(double x, double y) {
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Coordinates coordinates = new Coordinates(1, 2);
System.out.println("Bourne's current location - " + coordinates);
}
}
prints
Bourne's current location - Coordinates#addbf1 //concise, but not really useful to the reader
Now, overriding toString() in the Coordinates class as below,
#Override
public String toString() {
return "(" + x + ", " + y + ")";
}
results in
Bourne's current location - (1.0, 2.0) //concise and informative
The usefulness of overriding toString() becomes even more when the method is invoked on collections containing references to these objects. For example, the following
public static void main(String[] args) {
Coordinates bourneLocation = new Coordinates(90, 0);
Coordinates bondLocation = new Coordinates(45, 90);
Map<String, Coordinates> locations = new HashMap<String, Coordinates>();
locations.put("Jason Bourne", bourneLocation);
locations.put("James Bond", bondLocation);
System.out.println(locations);
}
prints
{James Bond=(45.0, 90.0), Jason Bourne=(90.0, 0.0)}
instead of this,
{James Bond=Coordinates#addbf1, Jason Bourne=Coordinates#42e816}
Few implementation pointers,
You should almost always override the toString() method. One of the cases where the override wouldn't be required is utility classes that group static utility methods, in the manner of java.util.Math. The case of override being not required is pretty intuitive; almost always you would know.
The string returned should be concise and informative, ideally self-explanatory.
At least, the fields used to establish equivalence between two different objects i.e. the fields used in the equals() method implementation should be spit out by the toString() method.
Provide accessors/getters for all of the instance fields that are contained in the string returned. For example, in the Coordinates class,
public double getX() {
return x;
}
public double getY() {
return y;
}
A comprehensive coverage of the toString() method is in Item 10 of the book, Effective Java™, Second Edition, By Josh Bloch.
Whenever you access an Object (not being a String) in a String context then the toString() is called under the covers by the compiler.
This is why
Map map = new HashMap();
System.out.println("map=" + map);
works, and by overriding the standard toString() from Object in your own classes, you can make your objects useful in String contexts too.
(and consider it a black box! Never, ever use the contents for anything else than presenting to a human)
Correctly overridden toString method can help in logging and debugging of Java.
Coding:
public class Test {
public static void main(String args[]) {
ArrayList<Student> a = new ArrayList<Student>();
a.add(new Student("Steve", 12, "Daniel"));
a.add(new Student("Sachin", 10, "Tendulkar"));
System.out.println(a);
display(a);
}
static void display(ArrayList<Student> stu) {
stu.add(new Student("Yuvi", 12, "Bhajji"));
System.out.println(stu);
}
}
Student.java:
public class Student {
public String name;
public int id;
public String email;
Student() {
}
Student(String name, int id, String email) {
this.name = name;
this.id = id;
this.email = email;
}
public String toString(){ //using these toString to avoid the output like this [com.steve.test.Student#6e1408, com.steve.test.Student#e53108]
return name+" "+id+" "+email;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
public String getEmail(){
return email;
}
public void setEmail(String email){
this.email=email;
}
}
Output:
[Steve 12 Daniel, Sachin 10 Tendulkar]
[Steve 12 Daniel, Sachin 10 Tendulkar, Yuvi 12 Bhajji]
If you are not used toString() in Pojo(Student.java) class,you will get an output like [com.steve.test.Student#6e1408, com.steve.test.Student#e53108].To avoid these kind of issue we are using toString() method.
Apart from what cletus answered with regards to debugging, it is used whenever you output an object, like when you use
System.out.println(myObject);
or
System.out.println("text " + myObject);
The main purpose of toString is to generate a String representation of an object, means the return value is always a String. In most cases this simply is the object's class and package name, but on some cases like StringBuilder you will got actually a String-text.
/**
* This toString-Method works for every Class, where you want to display all the fields and its values
*/
public String toString() {
StringBuffer sb = new StringBuffer();
Field[] fields = getClass().getDeclaredFields(); //Get all fields incl. private ones
for (Field field : fields){
try {
field.setAccessible(true);
String key=field.getName();
String value;
try{
value = (String) field.get(this);
} catch (ClassCastException e){
value="";
}
sb.append(key).append(": ").append(value).append("\n");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return sb.toString();
}
If you learn Python first and then Java. I think it plays the same role as __str__() method in Python, it is a magic method like __dict__() and __init__() but to refer to a string representing the the object.
the toString() converts the specified object to a string value.

Categories

Resources