Create ID for each object in a ListObjectClass - java

I have two classes, my object class, and the ListObjectClass.
In my constructor of ListObjectClass I create an array of an object looking like this:
private ObjectClass[] name;
And I have to make an ID for each ObjectClass, but I don't know how can I do that, do I need to make a getID() and setID() on ObjectClass?
Constructor of ListObject Class:
private int id;
private float pes;
private int nRegistres;
private RellotgeObjecte[] rellotge;
public LlistaRegistreEsportiu(int n) {
this.nRegistres = 0;
rellotge = new RellotgeObjecte[n];
}

You can pass the ID as an argument of the constructor:
public LlistaRegistreEsportiu(int n, int id) {
this.nRegistres = 0;
rellotge = new RellotgeObjecte[n];
this.id = id;
}

Related

Setter without parameter Java OOP

I wanted to create an employeeID automatically whenever I create a new employee object. I am implementing OOP concept for my assignment. My problem is I wanted to use getter and setter to create for the id. However, since the id should be generated automatically so I can't put any value for the parameter when creating instance. How can I solve this?
private String employeeID;
public void setEmployeeID(String employeeID){
Random rand = new Random();
int randint = rand.nextInt(100000);
char subId = 'E';
employeeID = subId + String.valueOf(randint);
this.employeeID = employeeID;
}
public String getEmployeeID(){
return employeeID;
}
To keep it simple:
You need or want to use public void setEmployeeId(String id) and its a basic requirement.
But if so, the idea of having such a method means that the class Employee should have any logic of id generation, instead by declaring such a method you say to the programmer that will use the Employee class: "Look, this class doesn't have an id, but you can create it and set".
If these are your intentions, then extract the logic of the id generation outside the employee class and use the "pure" setter:
main:
String id = generateId(...) // in this method there will be all the code with Random
Employee emp = new Employee();
emp.setId(id);
.....
class Employee {
private String id;
public void setId(String id) {this.id = id;}
}
Otherwise, if you do think that the Employee should generate an id by its own, you don't need a setter. In this case you can either call the generation code in constructor (not really recommended, but will work) or create an "init" method that will set the initial state of id to the employee object. In this case, whoever creates an Employee, will have to call this method:
public class Employee {
private String employeeId;
public class Employee(...) {...}
public void init() {
setupId();
}
private void generateEmpId() {
Random rand = new Random();
int randint = rand.nextInt(100000);
char subId = 'E';
employeeID = subId + String.valueOf(randint);
this.employeeID = employeeID;
}
}
Then in the main:
main:
Employee e = new Employee();
e.init(); // otherwise id won't be generated
This is not really convenient because whoever uses creates the Employee object will have to call init on it. In this case you might consider a factory method:
public class Employee {
private final String name;
private String empId;
private Employee(String name) {
this.name = name;
}
public static Employee create(String name) {
Employee emp = new Employee(name);
emp.init();
}
private void init() {
setupId();
}
private void generateEmpId() {
Random rand = new Random();
int randint = rand.nextInt(100000);
char subId = 'E';
employeeID = subId + String.valueOf(randint);
this.employeeID = employeeID;
}
}
Notice that the constructor is private now, which means that the only way to create Employee from main is using the create method. The init method also went private:
main:
Employee emp = Employee.create("John");
// the id is created - no need to remember to call "init" like in the previous example
Employee class should look like:
public class Employee {
private String employeeID;
public Employee() {
}
public void setEmployeeId(String employeeID){
this.employeeID = employeeID;
}
public String getEmployeeId(){
return employeeID;
}
}
From the class you want to assign new id, use the following:
public String generateId(String subId) {
Random rand = new Random();
int randint = rand.nextInt(100000);
return subId.concat(String.valueOf(randint));
}
Employee employee = new Employee();
employee.setEmployeeId(generateId('E'));
public class Emp {
private String id;
public Emp(){
id=getRandomId();
}
public void setId(String x){
id=new String(x);
}
public String getId(){
return new String (id);
}
public static String getRandomId(){
Random rand = new Random();
return "E"+rand.nextInt(100000);
}
}
getRandomId will return a random id.

The constructor Teacher(Teacher) is undefined

I am using a copy constructor and Inheritance in a class called 'Department' to call the information from class 'Teacher' which is a sub-class of 'Person'. After creating my set/get methods, I get the above error. Anyone have any insight as to why this is occurring?
Code from 'Department' class:
public class Department {
private String deptName;
private int numMajors;
private Teacher[] listTeachers; //inherits from Person class
private Student[] listStudents; //inherits from Person class
// First constructor for Department
public Department(String dn, int nm, Teacher[] listTeachers, Student[] listStudents) {
this.deptName = dn;
this.numMajors = nm;
this.listTeachers = new Teacher[listTeachers.length];
for (int i = 0; i < this.listTeachers.length; i++)
{
this.listTeachers[i] = new Teacher (listTeachers[i]);
}
//set method for Teachers Array
public void setListTeachers (Teacher[] other) {
this.listTeachers = new Teacher[other.length];
for (int i = 0; i < listTeachers.length; i++) {
this.listTeachers[i] = new Teacher (other[i]);
}
}
//get method for Teachers Array
public Teacher[] getListTeachers() {
Teacher[] copyTeachers = new Teacher[listTeachers.length];
for (int i = 0; i < copyTeachers.length; i++) {
copyTeachers[i] = new Teacher(this.listTeachers[i]);
}
return copyTeachers;
}
Here are the lines giving me errors:
1) this.listTeachers[i] = new Teacher (listTeachers[i]);
2) this.listTeachers[i] = new Teacher (other[i]);
3) copyTeachers[i] = new Teacher(this.listTeachers[i]);
Code from 'Teacher' class:
public class Teacher extends Person {
private String id;
private int salary;
private int num_yr_prof;
//Constructor for use in Teacher main method.
public Teacher(String n, int a, String s, boolean al, String i, int sal, int numyr) {
super(n, a, s, al);
this.id = i;
this.salary = sal;
this.num_yr_prof = numyr;
}
//Copy constructor for use in Department class.
public Teacher (String n, int a, String s, boolean al, Teacher other) {
super(n, a, s, al);
if (other == null) {
System.out.println("Fatal Error!");
System.exit(0);
}
this.id = other.id;
this.salary = other.salary;
this.num_yr_prof = other.num_yr_prof;
}
Your copy constructor might look like this:
public Teacher(Teacher teacher) {
this( teacher.n, teacher.a, teacher.s, teacher.al,
teacher.id, teacher.salary, teacher.num_yr_prof );
}
Since you do not show the code for the Person class, I have used the variable names n, a, s, and al here. They should be replaced by whatever those variables are named in the Person class. This, of course, assumes that those variables are either public or protected. If they are private, you need to use the getters for those variables (preferred even if they are public or protected).
You need to to your Teacher class a constructor that accepts a Teacher:
public Teacher(Teacher teacher) {
// do something
}

Reference leaks in copy constructor

I understand what is the reference leak and can deal with it, but I'm confused now when I had to write a copy constructor. Does the copy constructor cause leaks too?
public class Student {
private final int ID;
private final String studentName;
private double[] Grades = new double[5];
// constructor:
public Student(int ID, String Name, double[] quizGrades) {
this.ID = ID;
this.studentName = Name;
this.Grades = new double[quizGrades.length]; // use new to avoid REFERENCE LEAKS...
for (int k = 0; k < quizGrades.length; k++) //
this.Grades[k] = quizGrades[k]; //
}
// Copy constructor:
public Student(Student stu) {
this(stu.ID, stu.studentName, stu.Grades);
}
}
I made a copy of array quizGrades so there will not be a leak, but I am not sure whether the copy constructor is fine or not.

How to map enums to integers implicitliy

I know I'm not using the right jargon, but basically I want to take this code in C++ and port it over to Java
public enum Packets {
// Maps enums to integers 0-3
PACKET_NONE = 0, PACKET_SYNC,
PACKET_EXPECT_TO_RECEIVE, PACKET_AVAIL_1,
// Maps enums to integers 13-16
PACKET_FILL = 13, PACKET_GLASS, PACKET_FILLi, PACKET_GLASSi
}
I want to explicitly map an enum to an int, and then have every subsequent enum implicitly map to the next increment of that integer (or some solution as close to this C code as possible).
In Java you can assign values to Enum if that's what you are looking for. It will look like this:
public enum Packets {
PACKET_NONE(0),
PACKET_SYNC(1),
PACKET_EXPECT_TO_RECEIVE(2),
PACKET_AVAIL_1(3);
private int value;
Packets(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
Now you can call enum like this to get it's value:
Packets.PACKET_SYNC.getValue(); //It will return 1
You can add a field to your enum, intialize this field in the enumeration constant's constructor call and then return this field from a public getter. This should look about like this:
public enum Packets
{
PACKET_NONE(0),
PACKET_SYNC(1),
PACKET_EXPECT_TO_RECEIVE(2),
PACKET_AVAIL_1(3),
PACKET_FILL(13),
PACKET_GLASS(14),
PACKET_FILLI(15),
PACKET_GLASSI(16);
private final int id;
private MyEnum(final int id) {
this.id = id;
}
public final int getId() {
return index;
}
}
This is not that clean of a solution but if you really want to auto-initialize them to increment the same way the C++ declaration does, without explicitly defining each individual ID, you can do something like this:
public enum Packets
{
PACKET_NONE(0),
PACKET_SYNC(1),
PACKET_EXPECT_TO_RECEIVE(2),
PACKET_AVAIL_1(3),
PACKET_FILL(13),
PACKET_GLASS(),
PACKET_FILLI(),
PACKET_GLASSI();
private int id;
private Packets(int id) {
this.id = id;
}
private Packets(){
this.id = -1;
}
public final int getId() {
return id;
}
public void setId(int id){
this.id = id;
}
public static void initIds(){
for(Packets p : Packets.values()){
if(p.getId()==-1){
if(p.ordinal()==0){
p.setId(0);
}else{
p.setId(Packets.values()[p.ordinal()-1].getId()+1);
}
}
}
}
}
Then you call the initialize and it will fill in the ID's for you:
Packets.initIds();
System.out.println(Packets.PACKET_AVAIL_1.getId()); //3
System.out.println(Packets.PACKET_GLASS.getId()); //13
System.out.println(Packets.PACKET_FILL.getId()); //14
System.out.println(Packets.PACKET_FILLI.getId()); //15
edit/addition:
If you move the code from the initIds()method into a static initializer block, you do not need the initialize call somewhere in your code:
public enum Packets {
PACKET_NONE(0),
PACKET_SYNC(1),
PACKET_EXPECT_TO_RECEIVE(2),
PACKET_AVAIL_1(3),
PACKET_FILL(13),
PACKET_GLASS(),
PACKET_FILLI(),
PACKET_GLASSI();
static {
for (Packets p : Packets.values()) {
if (p.getId() == -1) {
if (p.ordinal() == 0) {
p.setId(0);
} else {
p.setId(Packets.values()[p.ordinal() - 1].getId() + 1);
}
}
}
}
private int id;
private Packets(int id) {
this.id = id;
}
private Packets() {
this.id = -1;
}
public final int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}

java builder pattern usage [duplicate]

This question already has answers here:
When would you use the Builder Pattern? [closed]
(13 answers)
Closed 7 years ago.
Recently I saw some of the developers coding their VOs with nested builder class like
public class User {
private String firstName;
private String lastName;
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 static class UserBuilder {
private String firstName;
private String lastName;
public User build() {
User user = new User();
user.firstName = firstName;
user.lastName = lastName;
return user;
}
public UserBuilder withFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public UserBuilder withLastName(String lastName) {
this.firstName = firstName;
return this;
}
}
}
Now, they claim that this makes code more readable. My point is, this has following disadvantages:
I can't simply add fields and expect my IDE to complete code for me, as now I need to update this inner class too.
Simple POJOs are carrying code which is not relevant for VO.
I am looking for any advice if I am missing something here. Feel free to add your thoughts about the same.
Sample code after this modification looks like,
User user = new User.UserBuilder()
.withFirstName("Name")
.withLastName("surName")
.build();
Here is an article from Joshua Bloch. He explains very well why, when and how to use a builder : http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2
It is one of items in his book called Effective Java. I strongly advise you to read this book if you have a little experience with Java.
Main point :
When you you get a class with a lot of attribute there is several ways create an object and init it.
If you set one by one every attributes it can be wordy and your object could be altered after its creation. With this method it is impossible to make your class immutable and you cannot be sure that your object is in consistent state.
Exemple from the article :
public class NutritionFacts {
// Parameters initialized to default values (if any)
private int servingSize = -1; // Required; no default value
private int servings = -1; // " " " "
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() { }
// Setters
public void setServingSize(int val) { servingSize = val; }
public void setServings(int val) { servings = val; }
public void setCalories(int val) { calories = val; }
public void setFat(int val) { fat = val; }
public void setSodium(int val) { sodium = val; }
public void setCarbohydrate(int val) { carbohydrate = val; }
}
You can use a telescoping constructor. It can make your object immutable. However if you get many attributes it can be hard to write and read your code. More over when you just want create with one setted attribute, and unfortunately this one is the last parameter of the constructor, you have to set all parameter anyway.
Exemple from the article :
public class NutritionFacts {
private final int servingSize; // (mL) required
private final int servings; // (per container) required
private final int calories; // optional
private final int fat; // (g) optional
private final int sodium; // (mg) optional
private final int carbohydrate; // (g) optional
public NutritionFacts(int servingSize, int servings) {
this(servingSize, servings, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories) {
this(servingSize, servings, calories, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat) {
this(servingSize, servings, calories, fat, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium) {
this(servingSize, servings, calories, fat, sodium, 0);
}
public NutritionFacts(int servingSize, int servings,
int calories, int fat, int sodium, int carbohydrate) {
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}
The builder allows to make your code more readable and easy to write. It also allows you to be able to make your class immutable.
Exemple from the article :
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
In your example I'm not sure that it is very useful to do a builder for a class with only two attributes.
I hope this will help you.
IMHO in the given example you gain no value by using Builder pattern. You can create User object without the Builder (because of all the setters). The only thing that Builder gives you in this particular case is Fluent Interface.
You should use Builder Pattern when there are various combinations of creating a valid object. Thanks to this you won't have to implement many constructors or factory methods.
Builder is also helpful when creating a valid object requires many parameters.
Builder should be responsible for build only a valid objects. In your case, if User needs to have first and last name Builder shouldn't allow to create the instance of User that doesn't have those attributes set.
Start with small immutable objects
If all your properties are required then you should use just constructor. By doing this you might create nice small immutable object.
Builders are helpful when you have multiple optional fields
If there are multiple optional fields and different ways to create an object you'd need multiple constructors.
public User (int requiredParameter) { ... }
public User (int reqiredParameter, int optionalParameter) { ... }
public User (int reqiredParameter, int optionalParameter, String optionalParameter2) { ... }
public User (int reqiredParameter, String optionalParameter2) { ... }
It creates messy code. It is hard to determine which constructor you should use.
In this case you could use nested builder to have intuitive way of creating your object.

Categories