I think I have got myself into a bit of muddle. I had teacher and student below in two separate addMember sections. For the purpose of what I am doing they have to in one section but when someone wants to add either student or teacher they need to be able to be added separately (so one call which will give the option of adding either). But my knowledge of arrayLists is not very good and as you can see isn't working very well. Any help be much needed and appreciated.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Committee {
private String name;
private List<Object> members;
public Committee(String name)
{
this.name = name;
members = new ArrayList<Object>();
List list = new ArrayList();
}
public void addMember(Student student, Teacher teacher)
{
List members1 = new ArrayList();
members1.add(student);
System.out.println(members1);
List members2 = new ArrayList();
members2.add(teacher);
System.out.println(members2);
}
public void printMembership()
{
System.out.println("Membership of the " + name + " Committee ");
Iterator<Object> it = members.iterator();
while (it.hasNext())
{
Object member = it.next();
System.out.println(members);
}
}
}
I'm not sure what you want to achieve, so I will write two solutions:
Situation where you want to have one list
interface Member {...}
class Student implements Member {...}
class Teacher implements Member {...}
public class Comittee {
private list<Member> members;
public void addMember(Member member) {
members.add(member);
}
public void printMembership() {
members.forEach(System.out::println);
}
}
Situation where you want to have two lists
interface Member ...
class Student implements Member ...
class Teacher implements Member ...
public class Comittee {
private list<Teacher> teachers;
private list<Student> students;
public void addMember(Student student, Teacher teacher) {
students.add(student);
teachers.add(teacher);
}
public void printMembership() {
getAllMembers().forEach(System.out::println);
}
private void getAllMembers(): List<Member> {
List<Member> allMembers = ArrayList<>(students.size() + teachers.size());
allMembers.addAll(teachers);
allMembers.addAll(students);
return allMembers;
}
}
Related
I have a class named "classroom" and i want send one arraylist with classroom.setMaterias(Arraylist). Is this code:
Class Clasroom
public class Aula implements java.io.Serializable {
private String nombre;
private String grupo;
private int tutor;
ArrayList<String> materias = new ArrayList<String>(); // ¿How create arraylist?
public Aula() {
// Constructor
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
I would like to know if I could, for example, send an "arraylist" through a SET and then make the "arraylist" that I created previously in my class "classroom" be exactly the same
I would not know how to create the arraylist, or the set or get methods. Can you help me please?
PD: This is the JSON ARRAY i talking about:
if (obj.has("materias")) {
JSONArray materias = obj.getJSONArray("materias");
datos.setArrayList(materias);
// System.out.println(materias); // ["DWES","DWEC","IW","DAW","IE"]
Class Clasroom
public class Aula implements java.io.Serializable {
private String nombre;
private String grupo;
private int tutor;
ArrayList<String> materias; // ¿How create arraylist?
public Aula() {
// Constructor
this.setArrayList(new ArrayList<>()); //Here you initialize the arraylist when you create an instance of this class.
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
//Here are the getters and setters.
public ArrayList<String> getList(){
return this.materias;
}
private void setArrayList(ArrayList<String> list){
this.materias = list;
}
The proper way of doing it is using getters and setters and using List interface rather than ArrayList<> directly.
List<String> materias = Collections.emptyList();
public Aula() {
// Constructor
}
public List<String> getMaterias() {
return materias;
}
public void setMaterias(List<String> materias ) {
this.materias = materias ;
}
public void addMaterias(String materia) {
materias.add(materia);
}
You can have additional addMaterias() method to add entries to your List.
public class Aula implements java.io.Serializable {
private List<String> materia = new ArrayList<>();
...
public void setMateria1(final List<String> aMateria) {
this.materia = aMateria;
}
public void setMateria2(final List<String> aMateria) {
this.materia.clean();
this.materia.addAll(aMateria);
}
}
setMateria1() replaces the list with the given argument, thus any changes (EG deletion of items,) made later to the one, is reflected in the other.
While setMateria2() copies the argument's items, thus deletion or insertion to any of them does not change the other one.
Also ArrayList is a concrete implementation of the interface List. It is preferable to declare variables as the base class or interface, instead of a concrete implementation.
public class Aula implements java.io.Serializable {
ArrayList<String> materias = new ArrayList<String>();
...
public ArrayList<String> getMaterias(){
return materias;
}
public void setMaterias(JSONList materias) throws JSONException {
materias.clear();
for(int i=0;i<materias.length();i++)
this.materias.add(materias.getString(i));
}
}
And put the exact same code into the classroom class.
Second way is to set the Lists in the constructor:
public class Aula implements java.io.Serializable {
ArrayList<String> materias = new ArrayLis<>();
...
public Aula(JSONList materias) throws JSONException {
for(int i=0;i<materias.length();i++)
this.materias.add(materias.getString(i));
}
public ArrayList<String> getMaterias(){
return materias;
}
}
Again same for classroom. And than you create them eg.
Aula aula = new Aula(materias);
Classroom classroom = new Classroom(materias);
This is assuming you have Strings in your list. Otherwise it depends on your data in the list.
If it contains other Lists it they need to be merged or skipped and so on...
If the json is not all Strings(e.g. has Sublists and Objects) and it should match the actual structure of your json I'd need that structure too and most probably an Arraylist of Strings might be the wrong Container for such a json - tree.
btw. better change classroom to Classroom(capital C for the classname) ...
Is there any way to create new class variable or method in java without editing class java
Example:
I have class Person
public class Person {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
and in main class I process like this:
Person personData = new Person();
personData.setName("My Name");
personData.setAddress("Address");
List<Person> person = new ArrayList<Person>();
person.add(personData);
I want to add new person variable in List
and have setNo(); and getNo();
So list index[0] have person with property No, Name, And Address without editing the class Person first.
There is no way in Java to add methods to a class without changing the class source code.
The only possibility you have is to either extend from this class (by creating a subclass that inherits from Person) or to create a completely new class that contains a Person object.
The first concept is called inheritance; the second one composition. You can find a discussion of "one versus the other" here for example.
But in essence the answer: step back and read a good book about Java.
I would probably create another class which extends Person.
import java.util.ArrayList;
import java.util.List;
public class PersonNo extends Person {
public static void main(String[] args) {
PersonNo personData = new PersonNo();
personData.setName("My Name");
personData.setAddress("Address");
List<PersonNo> person = new ArrayList<>();
person.add(personData);
}
public void setNo(int n) {
this.no = n;
}
public int getNo() {
return this.no;
}
private int no;
}
This requires you to change the List type to "PersonNo" and to add "PersonNo"s, but it will give you the functionality you need. If you create the List with "Person", you can add "PersonNo"s but you will not have the setNo/getNo unless you cast the "Person" into a (PersonNo).
I want to implement a composite pattern in Java in order to map a software development organization. So, let's assume there are multiple project managers and multiple developers. Each developer is assigned to exactly one project manager and each developer is able to code in various programming languages. The project managers lead the developers and know exactly their workload.
I am not a hundred percent sure about this design pattern, but I think that it is the perfect use case for this scenario, isn't it?
The result should be as follows:
I want to query the project manager to check the workload of all developers which are able to code in a specific programming language, e.g. Java.
Here is what I have so far:
Employee.java:
public class Employee {
private String name = null;
public Employee() {
name = "Noob";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ProgrammingLanguages.java:
public enum ProgrammingLanguages {
JAVA,
JAVASCRIPT,
C,
PHP,
SWIFT,
PYTHON
}
ProjectManager.java:
import java.util.ArrayList;
import java.util.List;
public class ProjectManager extends Employee {
private List<Employee> employeeList = null;
public ProjectManager() {
employeeList = new ArrayList<Employee>();
}
public List<Employee> getEmployees() {
return employeeList;
}
public void setEmployees(List<Employee> employees) {
employeeList = employees;
}
public int getTotalWorkload() {
int workload = 0;
for (Employee employee : employeeList) {
workload += employee.getWorkload(); // Error! Cannot resolve method 'getWorkload()'
}
return workload;
}
}
Developer:
import java.util.ArrayList;
import java.util.List;
public class Developer extends Employee {
private List<ProgrammingLanguages> languagesList = null;
private int workload = 0;
public Developer() {
languagesList = new ArrayList<ProgrammingLanguages>();
}
public void setLanguagesList(List<ProgrammingLanguages> languagesList) {
this.languagesList = languagesList;
}
public void addProgrammingLanguage(ProgrammingLanguages language) {
languagesList.add(language);
}
public List<ProgrammingLanguages> getLanguagesList() {
return languagesList;
}
public void setWorkload(int workload) {
this.workload = workload;
}
public int getWorkload() {
return workload;
}
}
Unfortunately, I get a compiler error in my ProjectManager class, any idea why?
Thanks in advance.
I am not a hundred percent sure about this design pattern, but I think that it is the perfect use case for this scenario, isn't it?
The GoF structure of Composite is as follows:
As you can see, Operation() is common in all elements. That would be your scenario's getWorkload() method.
However, it's somewhat inconsistent with the pattern in that it implies that a Manager has a workload that is composed of her employees. It's the contrary in real life, at least with a good manager. I would suggest changing the method name to something like getEffortUnderMyResponsibility(), to imply a responsibility for getting the work done, rather than actually doing the work. For programmers, it's true they actually do it; for managers, they are responsible for it getting done.
Yes, the composite pattern is indeed the right choice if you want to map tree structures. With reference to your example, the composite design pattern implies that your class Employee acts as a node, the class ProjectManager acts as a branch and the class Developer acts as a leaf. Within this context, the main advantage of the composite pattern is that it treats objects of your compositions uniformly. As a result, you can represent entire hierarchies of instances with this particular GoF design pattern.
You need the following participants:
The abstract class Employee must declare the interface of the composition and implements a common behaviour to a certain degree.
The ProjectManager class extends the abstract class Employee and implements a behaviour to treat Employee children, i.d. in your case ProjectManager or Developer instances.
The Developer also extends the abstract class Employee and represents a leaf which does not have any children.
I used your example code to demonstrate the composite pattern. Please note that it may vary from your desired outcome, but you can take it as a reference.
Employee.java (node):
package me.eckhart;
import java.util.List;
public abstract class Employee {
private String name = null;
public static final String OPERATION_NOT_SUPPORTED = "Operation not supported.";
public String getName() {
return name;
}
public Employee setName(String name) {
if (name == null) throw new IllegalArgumentException("Argument 'name' is null.");
this.name = name;
return this;
}
public Employee addEmployee(Employee employee) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public List<Employee> getEmployees() {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee setEmployees(List<Employee> employees) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee setLanguagesList(List<ProgrammingLanguages> languagesList) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee addProgrammingLanguage(ProgrammingLanguages language) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public List<ProgrammingLanguages> getLanguagesList() {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
/* Composite operations. */
public abstract int getWorkload(ProgrammingLanguages language);
public abstract Employee setWorkload(int workload);
}
ProjectManager.java (branch):
package me.eckhart;
import java.util.ArrayList;
import java.util.List;
public class ProjectManager extends Employee {
private List<Employee> employeeList = null;
public ProjectManager() {
this.employeeList = new ArrayList<>();
}
#Override
public Employee addEmployee(Employee employee) {
if (employee == null) throw new IllegalArgumentException("Argument 'employee' is null.");
this.employeeList.add(employee);
return this;
}
#Override
public List<Employee> getEmployees() {
return this.employeeList;
}
#Override
public Employee setEmployees(List<Employee> employeeList) {
if (employeeList == null) throw new IllegalArgumentException("Argument 'employeeList' is null.");
this.employeeList = employeeList;
return this;
}
/* Composite operations. */
public int getWorkload(ProgrammingLanguages language) {
int workload = 0;
for (Employee employee : employeeList) {
workload += employee.getWorkload(language);
}
return workload;
}
public Employee setWorkload(int workload) {
throw new UnsupportedOperationException(Employee.OPERATION_NOT_SUPPORTED);
}
}
Developer.java (leaf):
package me.eckhart;
import java.util.ArrayList;
import java.util.List;
public class Developer extends Employee {
private List<ProgrammingLanguages> languagesList = null;
private int workload = 0;
public Developer() {
this.languagesList = new ArrayList<>();
}
#Override
public Employee setLanguagesList(List<ProgrammingLanguages> languagesList) {
this.languagesList = languagesList;
return this;
}
#Override
public Employee addProgrammingLanguage(ProgrammingLanguages language) {
this.languagesList.add(language);
return this;
}
#Override
public List<ProgrammingLanguages> getLanguagesList() {
return this.languagesList;
}
/* Composite operations. */
public Employee setWorkload(int workload) {
if (workload < -1) throw new IllegalArgumentException("Workload cannot be negative.");
this.workload = workload;
return this;
}
public int getWorkload(ProgrammingLanguages language) {
if (this.languagesList.contains(language)) return workload;
return 0;
}
}
ProgrammingLanguages.java (enumeration):
package me.eckhart;
public enum ProgrammingLanguages {
JAVA,
JAVASCRIPT,
C,
PHP,
SWIFT,
PYTHON
}
I created a unit test to demonstrate how you can access the workload for one particular programming language.
EmployeeTest.java (JUnit 4.11):
package me.eckhart;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class EmployeeTest {
protected Employee projectManagerIt;
#Before
public void setUp() throws Exception {
Employee webDevSr = new Developer();
webDevSr.setName("Jane").addProgrammingLanguage(ProgrammingLanguages.JAVASCRIPT).addProgrammingLanguage(ProgrammingLanguages.PYTHON).setWorkload(10);
Employee webDevJr = new Developer();
webDevJr.setName("Alex").addProgrammingLanguage(ProgrammingLanguages.PHP).setWorkload(15);
Employee projectManagerWebDev = new ProjectManager();
projectManagerWebDev.setName("James").addEmployee(webDevSr).addEmployee(webDevJr);
Employee softwareDevSr = new Developer();
softwareDevSr.setName("Martin").addProgrammingLanguage(ProgrammingLanguages.C).addProgrammingLanguage(ProgrammingLanguages.JAVA).setWorkload(35);
Employee softwareDevJr = new Developer();
softwareDevJr.setName("John").addProgrammingLanguage(ProgrammingLanguages.JAVA).setWorkload(30);
Employee projectManagerBackend = new ProjectManager();
projectManagerBackend.setName("Tom").addEmployee(softwareDevSr).addEmployee(softwareDevJr);
Employee freelanceSoftwareDev = new Developer();
freelanceSoftwareDev.setName("Marco").addProgrammingLanguage(ProgrammingLanguages.JAVA).addProgrammingLanguage(ProgrammingLanguages.PYTHON).addProgrammingLanguage(ProgrammingLanguages.C).setWorkload(25);
Employee freelanceWebDev = new Developer();
freelanceWebDev.setName("Claudio").addProgrammingLanguage(ProgrammingLanguages.SWIFT).addProgrammingLanguage(ProgrammingLanguages.JAVASCRIPT).addProgrammingLanguage(ProgrammingLanguages.PHP).setWorkload(10);
Employee freelanceProjectManager = new ProjectManager();
freelanceProjectManager.setName("Angie").addEmployee(freelanceSoftwareDev).addEmployee(freelanceWebDev);
projectManagerIt = new ProjectManager();
projectManagerIt.setName("Peter").addEmployee(projectManagerWebDev).addEmployee(projectManagerBackend).addEmployee(freelanceProjectManager);
}
#Test
public void testComposite() throws Exception {
Assert.assertEquals(90, projectManagerIt.getWorkload(ProgrammingLanguages.JAVA));
Assert.assertEquals(20, projectManagerIt.getWorkload(ProgrammingLanguages.JAVASCRIPT));
Assert.assertEquals(60, projectManagerIt.getWorkload(ProgrammingLanguages.C));
Assert.assertEquals(25, projectManagerIt.getWorkload(ProgrammingLanguages.PHP));
Assert.assertEquals(10, projectManagerIt.getWorkload(ProgrammingLanguages.SWIFT));
Assert.assertEquals(35, projectManagerIt.getWorkload(ProgrammingLanguages.PYTHON));
}
}
The UML class diagram looks like this:
The code in the setUp() method of EmployeeTest.java implements the following tree structure:
The main disadvantage of the composite design pattern is that you need to restrict certain operations with runtime-checks, since clients usually do not know whether they are dealing with a ProjectManager (branch) or a Developer (leaf) instance.
The method getWorkload() is not defined in class Employee and you're trying to access it.
In order to solve the compilation error you should add this method to Employee - I would add it as abstract in order to force any (new) sub-class to implement it.
BTW, that's not composition-pattern - that's inheritance. You can (and should) read more about it.
I'm a little stuck and would definitely appreciate your help. As the title says I want to store different classes on an array, which is in another class
This would be my code
The Customer class:
public class Customer {
public List<Product> products = new ArrayList<Product>();
public void addProduct(Product p){
products.add(p);
}
}
The Product class:
public abstract class Product{ }
The Ham class:
public class Jamon extends Product{
protected String marca;
protected int precio;
public Jamon(String marca,Double precio){
this.marca=marca;
this.precio=precio;
}
public void setMarca(String marca){
this.marca=marca;
}
public String getMarca(){
return marca;
}
public void setPrecio(int precio){
this.precio=precio;
}
public int getPrecio(){
return precio;
}
*/
public void comprar(){
System.out.println("Se ha comprado el jamon");
}
What I want to know is How do i store the Jamon class in the array on the Customer class, i want this because there will be multiple classes like Jamon that extend from Product. Also, if all this classes (Pepino, Jelly, etc) have precios, how can I add all the precios?
Thank you, if you have any doubt about my question please ask me (english is not my first language) Nice Day (:
Here's a small implementation of what you appear to be trying to achieve
public abstract class Product {
protected double precio;
public void setPrecio(double precio){
this.precio=precio;
}
public double getPrecio(){
return precio;
}
}
Here's another one
public class Jamon extends Product{
protected String marca;
public Jamon(String marca,Double precio){
this.marca=marca;
this.precio=precio;
}
public void setMarca(String marca){
this.marca=marca;
}
public String getMarca(){
return marca;
}
public void comprar(){
System.out.println("Se ha comprado el jamon");
}
}
Here's also this one
public class Pepino extends Product{
protected String marca;
public Pepino(String marca,Double precio){
this.marca=marca;
this.precio=precio;
}
public void setMarca(String marca){
this.marca=marca;
}
public String getMarca(){
return marca;
}
public void comprar(){
System.out.println("Se ha comprado el pepino");
}
}
And finally
import java.util.List;
import java.util.ArrayList;
public class Customer {
public List<Product> products = new ArrayList<Product>();
public void addProduct(Product p){
products.add(p);
}
public static void main(String[] args) {
Customer customer = new Customer();
Jamon jamon = new Jamon("Jabugo", 25.0);
Pepino pepino = new Pepino("Extra picante", 8.50);
Jamon negro = new Jamon("Pata Negra", 32.99);
customer.addProduct(jamon);
customer.addProduct(pepino);
customer.addProduct(negro);
for (Product product : customer.products) {
System.out.println(product.getClass());
}
}
}
Okay, so to be clear. Both Jamon and Pepino extend from Product, which means:
-Any variable (such as precio) or method (setPrecio or getPrecio) is available to them. Since its defined in the abstract class. One exception to this are the ones with private, those won't be accesible in the extending classes.
-Since customer adds a bunch of elements as Product there is no way to access the methods defined in Jamon or Pepino unless the item in the list is casted.
-It is not very common practice to declare an inner field a public variable (I'm referring to products in Customer, make a getter/setter).
-Also in your small example you seem to mix the ideas of double and int both represent numbers, but only the first has decimal point. If you are using decimal values, as it happens with precio, declare the field a double and work always with a double.
New Customer class (only storing prices, as oposed to Product, in the ArrayList)
import java.util.List;
import java.util.ArrayList;
public class Customer {
public List<Double> products = new ArrayList<Double>();
public void addProduct(Product p){
products.add(p.getPrecio());
}
public static void main(String[] args) {
Customer customer = new Customer();
Jamon jamon = new Jamon("Jabugo", 25.0);
Pepino pepino = new Pepino("Extra picante", 8.50);
Jamon negro = new Jamon("Pata Negra", 32.99);
customer.addProduct(jamon);
customer.addProduct(pepino);
customer.addProduct(negro);
for (Double productPrice : customer.products) {
System.out.println(productPrice);
}
}
}
As others have already commented, you can add an instance of any subclass of Product to an ArrayList<Product>. That you have done already.
If you want all products to have a precio, then you can define it on the abstract class Product instead of in Jamon and other subclasses. Move the declaration of the variable precio from Jamon to Product. Also move the methods getPrecio and setPrecio to Product. Create a constructor in Product to accept a precio. In constructors of subclasses such as Jamon, call super(precio) to initialize precio.
Then, you will be able to loop over all Products in your ArrayList and call the getPrecio() method to add up all precios.
Currently I have two classes. A Classroom class and a School class. I would like to write a method in the School class public void showClassRoomDetails which would find the classroom details by only using the teacherName.
e.g.
teacherName = Daniel className = Science
teacherName = Bob className = Maths
so when I input Bob, it would print out Bob and Maths
many, thanks
public class Classroom
{
private String classRoomName;
private String teacherName;
public void setClassRoomName(String newClassRoomName)
{
classRoomName = newClassRoomName;
}
public String returnClassRoomName()
{
return classRoomName;
}
public void setTeacherName(String newTeacherName)
{
teacherName = newTeacherName;
}
public String returnTeacherName()
{
return teacherName;
}
}
import java.util.ArrayList;
public class School
{
private ArrayList<Classroom> classrooms;
private String classRoomName;
private String teacherName;
public School()
{
classrooms = new ArrayList<Classroom>();
}
public void addClassRoom(Classroom newClassRoom, String theClassRoomName)
{
classrooms.add(newClassRoom);
classRoomName = theClassRoomName;
}
public void addTeacherToClassRoom(int classroomId, String TeacherName)
{
if (classroomId < classrooms.size() ) {
classrooms.get(classroomId).setTeacherName(TeacherName);
}
}
public void showClassRoomDetails
{
//loop
System.out.println(returnClassRoomName);
System.out.println(returnTeacherName);
}
}
Do you really need a list here ?
A Map holding classroom - teacher associations would be more helpful for what you're trying to achieve.
But there are also strange things in your code: for instance, why do you hold a classRoomName and teacherName as instance variables in your School class ?
Change your method signature to take a targetTeacherName as a parameter. Loop through the classrooms until you find one with that teacher. Output the information of that classroom.
Since you are using an ArrayList you could simply use a for each statement:
public void showClassRoomDetails(String teacherName)
{
for (Classroom classroom : this.classrooms)
{
if (classroom.returnTeacherName().equals(teacherName))
{
System.out.println(classroom.returnClassRoomName());
System.out.println(classroom.returnTeacherName());
break;
}
}
}
As a small suggestion, do not name your methods returnXxx(), use getXxx() instead, it is the standard Javabean convention.