So I'm relatively new to the game. I have a java class "Family" in which I want to implement a boolean method that tells me whether x is the sibling of y (true or false) etc.
public class Family {
private final Gender gender; // enum
private final String name;
private Family parent;
private Family firstChild;
private Family seccondChild;
private Family thirdChild;
public Family (final String name, final Gender gender) {
this.name = name;
this.gender = gender;
}
public String getName() {
return name;
}
public Gender getGender() {
return gender;
}
public Family getThirdChild() {
return thirdChild;
}
public void setThirdChild(Family thirdChild) {
this.thirdChild = thirdChild;
}
public void setSeccondChild(Family seccondChild) {
this.seccondChild = seccondChild;
}
public Family getSeccondChild() {
return seccondChild;
}
public Family getFirstChild() {
return firstChild;
}
public void setFirstChild(Family firstChild) {
this.firstChild = firstChild;
}
public Family getParent() {
return parent;
}
public void setParent(Family parent) {
this.parent = parent;
}
// So here is my problem I don't know how to show, that two children are siblings or not
public boolean isTheSiblingOf(Family x) {
if ( ) { // If y is sibling of x return true.. How??
return true;
}
return false;
}
public String toString() {
return "Family: " + name;
}
}
Here is the other class for my objects. As you can see I only refered to the mother. I need the father for something else, but not now.
Family theo = new Family("Theo", Gender.M); // Father
Family clara = new Family ("Clara", Gender.F); // Mother
Family john = new Family("John", Gender.M);
john.setParent(clara); // I'm only choosing one parent
clara.setFirstChild(john);
Family rachel = new Family("Rachel", Gender.F);
rachel.setParent(clara);
clara.setSeccondChild(rachel);
Family jennifer = new Family("Jennifer", Gender.F);
jennifer.setParent(clara);
clara.setThirdChild(jennifer);
I know you are learning, but try thinking about how to better your code. You should create some type of class Person, which is gonna have attributes like parents, name & children. then just add them to your Family class.
public class Person {
private Person mother;
private Person father;
private String firstName;
private String lastName;
private List<Person> children = new ArrayList<Person>();
public Person(Person mother, Person father, String firstName, String lastName) {
this.mother = mother;
this.father = father;
this.firstame = firstName;
this.lastName = lastName;
}
void addChildren(Person child) {
children.add(child);
}
// GETERS AND SETTERS
}
public class Family {
private String familyName;
private List<Person> familyMembers = new ArrayList<Person>();
public Family(String name) {
this.familyName = name;
}
public boolean areSiblings(Person person1, Person person2) {
if(person1.getMother().equals(person2.getMother())
&& person1.getFather().equals(person2.getFather())) {
return true;
} else {
return false;
}
}
}
Related
I have created a Person, class and a Professor class that both use the Builder Pattern to create objects. The Professor class takes a Person object as an argument in its constructor. I am trying to use both classes together, but when I attempt to print out a professor, get the following output: null null (instead of Bob Smith).
Here's what I tried so far:
Person:
public class Person {
private String firstname;
private String lastname;
private int age;
private String phoneNumber;
private String emailAddress;
private char gender;
public Person(){}
// builder pattern chosen due to number of instance fields
public static class PersonBuilder {
// required parameters
private final String firstname;
private final String lastname;
// optional parameters
private int age;
private String phoneNumber;
private String emailAddress;
private char gender;
public PersonBuilder(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
public PersonBuilder age(int age) {
this.age = age;
return this;
}
public PersonBuilder phoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
return this;
}
public PersonBuilder emailAddress(String emailAddress) {
this.emailAddress = emailAddress;
return this;
}
public PersonBuilder gender(char gender) {
this.gender = gender;
return this;
}
public Person build() {
return new Person(this);
}
}
// person constructor
private Person(PersonBuilder builder) {
this.firstname = builder.firstname;
this.lastname = builder.lastname;
this.age = builder.age;
this.phoneNumber = builder.phoneNumber;
this.emailAddress = builder.emailAddress;
this.gender = builder.gender;
}
#Override
public String toString() {
return this.firstname + " " + this.lastname;
}
}
Here's the Professor class:
package com.example.hardcodedloginform;
import java.util.List;
public class Professor extends Person{
private Person professor;
private double salary;
private String courseTaught;
private List<Student> students;
private int professorID;
public static class ProfessorBuilder {
// required fields
private Person professor;
private int professorID;
// optional fields
private double salary;
private String courseTaught;
private List<Student> students;
public ProfessorBuilder(Person professor, int professorID) {
this.professor = professor;
this.professorID = professorID;
}
public ProfessorBuilder salary(double salary) {
this.salary = salary;
return this;
}
public ProfessorBuilder courseTaught(String courseTaught) {
this.courseTaught = courseTaught;
return this;
}
public ProfessorBuilder students(List<Student> students) {
this.students = students;
return this;
}
public Professor build() {
return new Professor(this);
}
}
private Professor(ProfessorBuilder builder) {
this.salary = builder.salary;
this.courseTaught = builder.courseTaught;
this.students = builder.students;
}
#Override
public String toString() {
return "" + super.toString();
}
}
And here is the Main class where I try to print out a professor object:
public class Main {
public static void main(String[] args) {
Person profBobs = new Person.PersonBuilder("Bob", "Smith")
.age(35)
.emailAddress("bob.smith#SNHU.edu")
.gender('M')
.phoneNumber("818-987-6574")
.build();
Professor profBob = new Professor.ProfessorBuilder(profBobs, 12345)
.courseTaught("MAT101")
.salary(15230.01)
.build();
System.out.println(profBob);
}
}
I would like the printout in the console to be "Bob Smith", but what I am seeing is: null null. I checked and found that the Person object profBobs is, in fact, created properly and does print out the name "Bob Smith" when I attempt to print it the same way. I don't know why my Professor prints: null null.
Your Professor constructor fails to initialise any member fields of its base class.
There are multiple ways to solve this. One solution has ProfessorBuilder extend PersonBuilder:
public class Professor extends Person {
// Remove the `person` field! A professor *is-a* person, it does not *contain* it.
private double salary;
private String courseTaught;
private List<Student> students;
private int professorID;
public static class ProfessorBuilder extends Person.PersonBuilder {
// required fields
private int professorID;
// optional fields
private double salary;
private String courseTaught;
private List<Student> students;
public ProfessorBuilder(Person professor, int professorID) {
super(professor);
this.professorID = professorID;
}
// …
}
private Professor(ProfessorBuilder builder) {
super(builder);
this.salary = builder.salary;
this.courseTaught = builder.courseTaught;
this.students = builder.students;
}
}
For this to work you also need to mark the Person constructor as protected rather than private.
Furthermore, your Professor.toString method implementation made no sense: it essentially just called the base class method, so there’s no need to override it. And prepending the empty string does nothing.
I have three classes in my program. Ship.java, Cabin.java and Passenger.java. According to the program a single cabin should hold up to 3 passengers only. But I'm stuck on how to do this. I have created an array of cabin objects in my Ship.java class. I can only add one passenger into a cabin with below mentioned addCustomer method
Cabin[] cruiseShip = new Cabin[12];
for (int i = 0; i < cruiseShip.length; i++) {
cruiseShip[i] = new Cabin();
}
public static void addCustomer(Cabin[] cruiseShip, String firstName, String surName, int expenses, int cabinNumber){
if (cruiseShip[cabinNumber].getCabinName().equals("empty")){
cruiseShip[cabinNumber].setFirstName(firstName);
cruiseShip[cabinNumber].setSurName(surName);
cruiseShip[cabinNumber].setExpenses(expenses);
cruiseShip[cabinNumber].setCabinName("not empty");
System.out.println("Cabin number " + cruiseShip[cabinNumber].getCabinNumber() + " is occupied by " + cruiseShip[cabinNumber].getFirstName() + " " + cruiseShip[cabinNumber].getSurName() );
}
}
This is how Cabin.java looks :
public class Cabin extends Passenger {
int cabinNumber;
String cabinName;
public String getCabinName() {
return cabinName;
}
public void setCabinName(String cabinName) {
this.cabinName = cabinName;
}
public int getCabinNumber() {
return cabinNumber;
}
public void setCabinNumber(int cabinNumber) {
this.cabinNumber = cabinNumber;
}
}
This is how Passenger.java looks :
public class Passenger {
String firstName;
String surName;
int expenses;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public int getExpenses() {
return expenses;
}
public void setExpenses(int expenses) {
this.expenses = expenses;
}
}
Cabin should contain a data-structure which holds passengers.(association 1-n, from 1_cabin-N_passengers) You could also restrict the no. of passengers regarding to cabin type (up to 2-3-n passengers) and also check not to add n-times the same passenger in the same cabin for a specific time. Same logic with Ship which have Cabins.
class Cabin
{
... etc ... as u did
List<Passenger> listP = new ArrayList<Passenger>();
}
listP.add(new Passenger(...));
class Ship
{
...
List<Cabin> listC = new ArrayList<Cabin>();
}
listC.add(new Cabin(...));
//get a specific cabin from the ship and add a new Passenger
//note maybe it's better to do your custom methods for add,get_Ship, Cabin (based on the requiremts).
//Standard List Methods usually do not fit exactly custom requirements, so need to be enhanced
ship.getlistC().get(i_specificCabin).listP.add(new Passenger(...));
Be carefully not to mix semantics, think how in real world things works (see #Jim Garrison).
Note: Maybe a Map<String/Integer,CustomObject> can fit well for ease of access based on key(id).
Your relationship become as per your code is 1 Cabin have multiple Passager so relationship is OneToMany. The best and easiest way to solve your problem is Composition in java. You are working with Inheritance, It has IS-A relationship but Compostion has HAS-A relationship. Composition is best to worked on relationship.
Here down is code that solved your problem using `Composition Technique:
Passenger.java
public class Passenger {
String firstName;
String surName;
int expenses;
// No argument constructor
public Passenger() {
}
// All argument constructor
public Passenger(String firstName, String surName, int expenses) {
this.firstName = firstName;
this.surName = surName;
this.expenses = expenses;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public int getExpenses() {
return expenses;
}
public void setExpenses(int expenses) {
this.expenses = expenses;
}
}
Cabin.java
public class Cabin {
int cabinNumber;
String cabinName;
List<Passenger> passenger = new ArrayList<>();
// No argument constructor
public Cabin() {
}
// All argument constructor
public Cabin(int cabinNumber, String cabinName, List<Passenger> passenger) {
this.cabinNumber = cabinNumber;
this.cabinName = cabinName;
this.passenger = passenger;
}
public String getCabinName() {
return cabinName;
}
public void setCabinName(String cabinName) {
this.cabinName = cabinName;
}
public int getCabinNumber() {
return cabinNumber;
}
public void setCabinNumber(int cabinNumber) {
this.cabinNumber = cabinNumber;
}
public List<Passenger> getPassenger() {
return passenger;
}
public void setPassenger(List<Passenger> passenger) {
this.passenger = passenger;
}
}
Here down is Main class which insert record in Passanger and Cabin with relationship.
public static void main (String[] args) {
Cabin cabin = new Cabin();
// Insert and Put all Passanger in ArrayList
List<Passenger> passenger = new ArrayList<>();
passenger.add(new Passenger("Jack", "Crawly", 1000));
passenger.add(new Passenger("Michel", "Jordan", 2000));
passenger.add(new Passenger("Tim", "Leach", 3000));
if(cabin.getCabinName() == null)
{
// Insert Cabin with all Passenger
cabin = new Cabin(1, "Cabin1", passenger);
}
// Get all Passangers with Cabin
List<Passenger> passengers = cabin.getPassenger();
for (Passenger psg : passengers) {
System.out.println("Cabin Number : " + cabin.getCabinNumber());
System.out.println("FirstName : " + psg.getFirstName());
System.out.println("LastName : " + psg.getSurName());
System.out.println();
}
}
the student and teacher class inherited from person class, because inheritance is not flexible the object will either be one of the two. to solve this i added an abstract class Role and make association between person and role and student and teacher inherits from Role class so that an instance can has a role of both student and teacher.The question is to make instance of the Teacher class can also be a student or a student also teaches how to test in the main class?
public class Person {
private int ssn;
private String name;
private List<PersonRole> roles;
public Person(int ssn, String name) {
this.ssn = ssn;
this.name = name;
roles = new ArrayList<PersonRole>();
}
public int getSsn() {
return ssn;
}
public String getName() {
return name;
}
}
/////////////// PersonRole /////////////////
public abstract class PersonRole {
private List<PersonRole> learning;
private List<PersonRole> teaching;
public PersonRole(List<PersonRole> learning, List<PersonRole> teaching) {
this.learning = learning;
this.teaching = teaching;
}
public List<PersonRole> getLearning() {
return learning;
}
public List<PersonRole> getTeaching() {
return teaching;
}
public void addAsStudent(PersonRole p) {
learning.add(p);
}
public void addAsTeacher(PersonRole p) {
learning.add(p);
}
}
///////////// Teacher //////////////
public class Teacher extends PersonRole {
private String faultyName;
private int yearsOfExperence;
public Teacher(String faultyName, int yearsOfExperence) {
super();
this.faultyName = faultyName;
this.yearsOfExperence = yearsOfExperence;
}
public String getFaultyName() {
return faultyName;
}
public int getYearsOfExperence() {
return yearsOfExperence;
}
}
/////////// Student ////////////////
public class Student extends PersonRole {
private String collegeName;
private String major;
public Student(String collegeName, String major) {
super();
this.collegeName = collegeName;
this.major = major;
}
public String getCollegeName() {
return collegeName;
}
public String getMajor() {
return major;
}
}
////// Main ///////////////
public class Main {
public static void main(String[] args) {
PersonRole p1 = new Student("univ of Michigan", "CS");
PersonRole p3 = new Student("Iowa state univ", "managemnt");
PersonRole p2 = new Teacher("computer science", 3);
PersonRole p4 = new Teacher("Management", 2);
Person person = new Person(1042327867, "Mike Rose");
person.addRole(p1);
person.addRole(p2);
person.addRole(p3);
person.addRole(p4);
for (PersonRole c: roles) {
System.out.println(c);
}
}
}
I would test it exactly as you would but the hierarchy of inheritance looks good. Why not give PersonRole a constructor and attributes so that the children can use super() in their constructors and reuse some code?
Try this to print your roles:
List<PersonRole> roles = person.getRole();
for(PersonRole role: roles) {
System.out.println(role);
}
Then add a toString method in the Student and Teacher classes:
public String toString() {
return "Student {" + "collegeName=" + collegeName + ", major=" + major + '}';
}
public String toString() {
return "Teacher {" + "faultyName=" + faultyName + ", yearsOfExperence=" + yearsOfExperence + '}';
}
The result will be this:
Student {collegeName=maharashi univ, major=compro}
Teacher {faultyName=computer science, yearsOfExperence=3}
Student {collegeName=Iowa state univ, major=managemnt}
Teacher {faultyName=Management, yearsOfExperence=2}
I have the following structure:
Member {
String firstName;
String secondName;
Member[] children;
Member father;
}
I have to implement this tree in java;
I have a first name and a second name of a member. I need to find the way from root to that node.
Can someone help me, please?
This is what i have:
public class Member {
public List<Member> children = new ArrayList<>();
public Member father = null;
public String secondName = null;
public String firstName = null;
public Member(String secondName, String firstName) {
this.secondName = secondName;
this.firstName = firstName;
}
public Member(String secondName, String firstName, Member father) {
this.secondName = secondName;
this.firstName = firstName;
this.father = father;
}
public List<Member> getChildren() {
return children;
}
public void setFather(Member father) {
this.father = father;
father.addChild(this);
}
public void addChild(String secondName, String firstName) {
Member child = new Member(secondName, firstName);
child.setFather(this);
this.children.add(child);
}
public void addChild(Member child) {
child.setFather(this);
this.children.add(child);
}
public String getSecondName() {
return this.secondName;
}
public String getFirstName() {
return this.firstName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public void setPrenume(String firstName) {
this.firstName = firstName;
}
public boolean isRoot() {
return (this.father == null);
}
public void deleteFather() {
this.father = null;
}
}
Your structure is similar to ona which i have in my application. I solve this problem by creating generic walker, which walks down the three from the root, and using visitor pattern to provide me result of walk.
If you convert it into your problem it will looks like that:
public class SimpleWalker<T>{
private Visitor<T> visitor;
public SimpleWalker(Visitor<T> visitor) {
this.visitor= visitor;
}
public void walk(Member node) {
if (visitor.visit(node)) {
for (Member child : node.children) {
walk(child);
}
}
visitor.leave(node);
}
public T getResult() {
return visitor.getResult();
}
}
then visitor interface
public interface Visitor<T> {
boolean visit(Member node);
void leave(Member node);
T getResult();
}
and implementation will looks like that
public class Pathfinder implements Visitor<List<Member>> {
final private String firstname, secondname;//passed by constructor
boolean found = false;
List<Member> path = new ArrayList<>();
public boolean visit(Member node) {
if (node.firstname.equals(firstname)
&& node.secondname.equals(secondname)) {
found = true;
return false;
}
return true;
}
public void leave(Member node) {
if (found){
path.add(0, node);
}
}
public List<Member> getResult() {
return path;
}
}
advantage of this solution is, whatever you want to do something in tree, such us find element, count number of descendants of somebody, you can use walker, all what you need to do is create new visitor.
This Github project might help if you want to create a Family Tree using Java swing:
https://github.com/r-deleon/familyTree
It uses yFiles for Java library..
I want to find students whose gender is female by using streams
Student class
public class Student {
private String first;
private String last;
private int ID;
private Gender gender;
int next=0;
List<Course> courses=new LinkedList<>();
List<Student> students=new LinkedList<>();
public Student(String first, String last, int iD, Gender gender) {
this.first = first;
this.last = last;
ID = iD;
//this.gender = gender;
}
public void enroll(Course c) {
courses.add(c);
}
public void isFemale(){
Student s;
return s.gender=Gender.F;
}
}
enum class for genders
public enum Gender {
M,F;
private Gender gender;
}
main class
public class Main {
public static void main(String[] args) {
List<Student> studentsOfClass=new LinkedList<>();
studentsOfClass.add(new Student("john","smith",01,Gender.M));
studentsOfClass.add(new Student("mick","tayson",05,Gender.M));
studentsOfClass.add(new Student("sara","conor",04,Gender.F));
studentsOfClass.add(new Student("Tana","smith",02,Gender.F));
Course c1=new Course("fiologiya","anna",0234);
Course c2=new Course("mathematics","maria",1134);
Course c3=new Course("phisics","luisa",0534);
studentsOfClass.stream().limit(3).forEach(s->s.enroll(c1));
Collection<Student> femaleStudents= studentsOfClass.stream().filter(Student::isFemale).collect(Collectors.toList());
}
}
You are using the Stream methods correctly, but your isFamele method is wrong. It should return boolean and check the gender of the current Student.
It should be :
public boolean isFemale()
{
return gender==Gender.F;
}
You should also unremark this constructor line - //this.gender = gender; - and probably remove private Gender gender; from the Gender enum.
In addition, you can change the type of femaleStudents from Collection to List<Student>, which is more accurate.