Using static factory method, I want to create objects (e.g. persons), but throw an error/exception if a person with the same criteria is being created.
I have 2 classes Person.java / Program.java (<-Main)
My static method is as follow:
public class Person{
private String firstName;
private String lastName;
private Person(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public static Person fullName(String firstName, String lastName){
/*if(firstName.equals(this.firstName)){
System.out.println("Person already exists!");
}else{
return new Person(firstName,lastName);
}*/
return new Person(firstName, lastName);
}
}
Now obviously the commented-out part wouldn't work because Person isn't instanciated, but I'm kind of lost about how I could go on.
And yes, I'm overriding equals and hashcode!
To achieve it you should keep traces of all created instances in the Person class by using a static collection.
Note that it may cause memory retention if you don't use weak references for them and these are only referenced by the collection defined in Person.
Then about the check of an existing Person, as you overrided equals() and hashCode(), you could create a new Person from the parameters and check whether it was already created.
public class Person{
private String firstName;
private String lastName;
private static Set<Person> persons = new HashSet<>();
private Person(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
// equals and hashCode overrided relying on firstName and lastName fields
// ..
// Aditionnally to ease the creation of the exception message, override toString() too
#Override
public String toString(){
return "name=" + name +", lastName=" + lastName);
}
public static Person fullName(String firstName, String lastName){
Person p = new Person(firstName, lastName);
if (persons.contains(p)){
throw IllegalArgumentException("person " + p " already created";
}
persons.add(p);
return p;
}
}
Related
I am learning Java from tutorials, and recently I faced with one problem. I need to create several classes, and I need to read all that classes through first class. Already I passed that tutorial where I understood everything and tried that thing. But now I want to create a real world app on Java, I did the exact thing which was showing in tutorial, but I am getting that error. Please, correct me where I have mistaken
Code of first class:
package com.company;
public class Email {
private String firstName;
private String lastName;
private String password;
private String department;
private String alternateEmail;
private int capacityMailbox;
// Constructor to recieve the first name and last name
public Email(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
System.out.println(em);
}// Ask for the department
// Generate a random password
// Set the mailbox capacity
// Set the alternate email
// Change the password
}
Second one:
package com.company;
public class EmailApp {
public static void main(String[] args) {
// write your code here
Email em = new Email("John", "Smith");
}
}
Screenshotes:
Thanks
You can use System.out.println(this) in constructor. It means that you will print created instance to console. And also don't forget to override toString() method - because if you don't override it, you will get object's name with hashcode.
Hope this code will help you to reach the goal:
public class Email {
private String firstName;
private String lastName;
private String password;
private String department;
private String alternateEmail;
private int capacityMailbox;
// Constructor to recieve the first name and last name
public Email(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
System.out.println(this);
}
// Ask for the department
// Generate a random password
// Set the mailbox capacity
// Set the alternate email
// Change the password
#Override
public String toString() {
return "Email{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Another solution. Just override toString of Email class. And put printing of em to main method.
public class Email {
private String firstName;
private String lastName;
private String password;
private String department;
private String alternateEmail;
private int capacityMailbox;
// Constructor to recieve the first name and last name
public Email(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
// Ask for the department
// Generate a random password
// Set the mailbox capacity
// Set the alternate email
// Change the password
#Override
public String toString() {
return "Email{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Main class:
public class EmailApp {
public static void main(String[] args) {
// write your code here
Email em = new Email("John", "Smith");
System.out.println(em);
}
}
The constructor of your Email Class does not have a variable called em.
You should put System.out.println(em) into the Main method of your EmailApp class.
The object reference "em" has no scope in first class i.e. class Email.
make these following two changes and compare your code. you will understand where you went wrong.
//-----------------------------------------------------change 1
public Email(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
and in second class:
//---------------------------------------------change 2
public class EmailApp {
public static void main(String[] args) {
// write your code here
Email em = new Email("John", "Smith");
System.out.println(em.firstname);
System.out.println(em.lastname);
}
}
and make all member variables public for now. You will make it private when you understand "getters and setters" concept.
So within this class, I need to create a Equals method that will check to determine if the two objects have the same name. I tried creating the two objects within the class and just initialize it with "" for the constructor, but it gave an error on the created objects
Person.Java
public class Person
{
String firstName = "";
String lastName = "";
String age = "";
public Person (String firstName, String lastName, String age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String getAge(){
return age;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
public void setAge(String age){
this.age = age;
}
public String toString(){
return firstName + " " + lastName + ", " + age + " years old";
}
}
Here is my driver, so basically I need a method that sees both have the same name and prints out a message saying that they have the same name. My lab states it has to be in the class NOT the driver, which is why I'm lost considering I could easily make an if/else statement within the driver.
public class PersonDriver
{
public static void main(String[] args)
{
Person p1 = new Person("John","Doe", "42");
Person p2 = new Person("John","Doe", "43");
System.out.println(p1);
System.out.println(p2);
}
}
Getters and setters are used to implement two of the fundamental aspects of Object Oriented Programming which are
Abstraction
Encapsulation
Suppose we have an Employee class:
package com.highmark.productConfig.types;
public class Employee {
private String firstName;
private String middleName;
private String lastName;
public void getFirstName(){
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
// Similarly for lastName
public String getFullName(){
return this.getFirstName() + this.getMiddleName() + this.getLastName();
}
}
UPDATE : Is this usage right with the workerclass?
public class getNames() {
private String firstName;
private String middleName;
private String lastName;
//Constructor
public String getNames() {
Scanner input = new Scanner();
// output message to insert name part
String firstName = input.ReadLine();
String middleName = input.ReadLine();
String lastName = input.ReadLine();
Employee emp = new Employee();
emp.setFirstName(firstName);
emp.setMiddleName(middleName);
emp.setLastName(lastName);
}
}
Please try to explain the flaw in understanding if any.
Yes, you are correct on one thing for sure. Getters are Setters are a way to ensure the principle of Encapsulation in Object Oriented Programming languages like Java.
When you have a private member in your class, then its scope gets restricted to that particular class itself, but you may want to provide getters and/or setters to make that member accessible to classes outside your class.
Suppose you have a member like this,
private String firstName;
then this is your getter for this member,
public String getFullName(){
return this.getFirstName() + this.getMiddleName() + this.getLastName();
}
but this is not,
public String getFirstName() {
Scanner user_input = new Scanner(System.in);
firstName = user_input.next( );
return firstName;
}
because "getter" is just a term used to get the value of a member which is private. The sole purpose of a getter method is just to get the original value of a member.
In the latter method, the purpose is absolutely different. You are trying to get the first name as input, so technically it cannot be called a "getter" in any way.
Hope this clears your doubt.
Actually i am implementing one program in which i am retrieving information from database and i am setting that info to One Object using setters and i just want to print that Object parameters without using system.out.println(object.getHeadCount());
I just want like if i am giving system.out.println(object); so using this code it should print data in Json format or any other readable format.
How to do it.Because my object is containing 30 fields so it is very hectic to write 30 getters to print data.
You have to override toString()
Normal way
class User {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString(){
return this.firstName + " " + this.lastName;
}
}
Using Apache Commons
class User {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString(){
return new ToStringBuilder(this)
.append("firstName", firstName)
.append("lastName", lastName)
.toString();
}
}
Using Google Guava
class User {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString(){
return MoreObjects.toStringHelper(this)
.add("firstName", firstName)
.add("lastName", lastName)
.toString();
}
}
You simply have to override the toString() method of the class, read about it in java doc for Object class. Most IDE support it's automatic generation for all the fields of your class or for a number of them. Just for example:
class User {
private String name;
private String surname;
User(String name, String surname)
{
this.name = name;
this.surname = surname;
}
#Override
public String toString()
{
return this.name+" "+this.surname;
}
}
You should override toString() method. if you are using eclipse then you can try right-click within the editor, you'll find it under Source -> Generate toString()
To make a toString method you can simply just add one like so.
public String toString(){
return "" + getValue();
}
The toString method is a part of
java.lang.Object
So it is implemented in every class.
How do I create a class that has different lengths of arguments?
public static void main(String[] args) {
group g1 = new group("Redskins");
group g2 = new group("Zack", "Mills", 21);
group g3 = new group("John","Smith",20);
group g4 = new group("Fred","Fonsi",44);
group g5 = new group("Jeb","Bush",26);
System.out.println(g1.getName());
}
}
I want to be able to display the team name (redskins) and then each member after that using one method.
I've tried using two methods and got that to work, but can't get one.
I was thinking about possibly using an array but not sure if that would work.
Thanks for any help.
I have three classes the main, student, and group.
I need the group class to display the group name and then figure out how to display the students information underneath. The only thing, is that my assignment is vague about whether I can use two methods or one.
public class student {
String firstName;
String lastName;
int age;
student(String informedFirstName, String informedLastName, int informedAge){
firstName = informedFirstName;
lastName = informedLastName;
age = informedAge;
}
String getName()
{
return "Name = " + firstName + " " + lastName + ", " + "Age = " + age;
}
}
public class Team{
String name;
Set<Player> players;
public Team(String name){
this.name = name;
}
public void addPlayer(Player p){
players.add(p);
}
}
public class Player{
String name;
etc
}
EDIT for revised question:
Ok, Im going to show a lot here. Heres what a proper Java versio of what you want for student.
public class Student {
private String firstName;
private String lastName;
private int age;
public Student(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
/*
* Use:
* Student s = new Student(Bill, Nye, 57);
* System.out.println(s.toString());
*/
#Override
public String toString() {
return "First Name: " + firstName + ", Last Name: " + lastName + ", Age: " + age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
The Things to take away from this.
1) Capitalize the first letter of class names! (Student)
2) note the class variables are private (look here for a tutorial Java Class Accessibility) and have getters and setter to control access outside the class.
3) I dont say "getName()" and return name and age. This doesnt make sense. Instead i make it so when you go toString() it shows all the relevant information.
4) Java is an object oriented language which means the classes that model data are supposed (to some extent) model appropriately to the way they are used in real life. This makes it more intuitive to people reading your code.
5) if your Group class (note the capital!) needs to contain many Students use a LIST such as an ArrayList. Arrays would make no sense because you dont know how many Students are going to be in each Group. A SET like i used above is similar to a list but only allows ONE of each item. For simplicity use a list though
6) the THIS operator refers to class (object) variables. In the constructor this.firstName refers to the firstName within the Class (object...an instance of the class) whereas just firstName would refer to the variable in the contructor and not alter the class variable.
use the constructor for that
class group {
String fname,lname;
group(String fname ){
this.fname=fname;
}
group(String fname,String lname){
this.fname=fname;
this.lname=lname;
}
group(String fname,String lname,int age){
this.fname=fname;
this.lname=lname;
this.age=age;
}
public String getName(){
return fname+lname+age;
}
}