To demonstrate collection usage and a few other language constructs, I added a Department that has a list of employees. I also threw in a few maps for good measure. What follows is Java with the functional equivalents in Go Programming....
First I show in Java and then you use your knowledge of Java and some labels/comments I added to see the equivalent in GO
Java Department class
package com.example.collections; import java.util.ArrayList; import java.util.List; public class Department { private Listemployees = new ArrayList<>(); private String name; public Department(String name, Employee... employees) { this.name = name; for (Employee employee : employees) { this.employees.add(employee); } } public List getEmployees() { return employees; } public void setEmployees(List employees) { this.employees = employees; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Go Department class
package collections type Department struct { name string employees [] Employee } func NewDepartment(name string, employees ...Employee) *Department { return &Department{name, employees} } func (this *Department) Name() string { return this.name } func (this *Department) SetName(name string) { this.name = name } func (this *Department) Employees() []Employee { return this.employees } func (this *Department) SetEmployees(employees []Employee) { this.employees = employees }Now a new Company class to do some operations and construction of departments.
Now a new Company class to do some operations and construction of departments.
Java Company class
package com.example.collections; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Company { // (A) Create a map to hold employee id to hours worked this quarter private static MapempIdToHoursWorked = new HashMap<>(); // (B) Create a map to hold employee id to sales this quarter private static Map empIdToSales = new HashMap<>(); // (B.1) list of departments private static List departments = new ArrayList<>(); // (B.2) map of department names to departments private static Map deptNameToDepartment = new HashMap<>(); static { //(C) declare four departments Department sales =new Department("sales", new SalesEmployee(3L, "Whitney", "Hightower", 17,true, 0.05), new SalesEmployee(60L, "Alexander", "Hightower", 17,true, 0.05)); Department engineering =new Department("engineering", new Employee(1L, "Rick", "Hightower", 32, true), new HourlyEmployee(2L, "Bob", "Hightower", 27, true, 25.0)); Department hr =new Department("hr", new Employee(10L, "Diana", "Hightower", 32, true), new HourlyEmployee(20L, "Martha", "Hightower", 27, true, 25.0), new HourlyEmployee(30L, "Daniella", "Hightower", 27, true, 25.0)); Department manufacturing =new Department("manufacturing", new Employee(40L, "Joeseph", "Hightower", 32, true), new HourlyEmployee(50L, "John", "Hightower", 27, true, 25.0)); // (D) Bob worked 1750 hours this quarter. Martha and Daneilla each worked 350. How many did John work? empIdToHoursWorked.put(2L, 1750.0); empIdToHoursWorked.put(30L, 350.0); empIdToHoursWorked.put(20L, 350.0); empIdToHoursWorked.put(50L, 350.0); // (E) Whitney is our best sales person, but Alexander did good for a three year old. empIdToSales.put(60L, 5_000_000.0); empIdToSales.put(3L, 1_000_000.0); // (F) Add the three departments to the list of departments departments.add(engineering); departments.add(hr); departments.add(manufacturing); departments.add(sales); // (G) add some department to name mappings deptNameToDepartment.put(engineering.getName(), engineering); deptNameToDepartment.put(hr.getName(), hr); deptNameToDepartment.put(manufacturing.getName(), manufacturing); deptNameToDepartment.put(sales.getName(), sales); } // (H) Calculate Employee Cost public static double calculateCompanyEmployeeCost () { double totalCost = 0.0; //Nested for loop, looping over employees in each department. for (Department department : departments) { for (Employee employee : department.getEmployees()) { if (employee instanceof SalesEmployee) { ((SalesEmployee) employee).setQuarterlySales(empIdToSales.get(employee.getId())); } else if (employee instanceof HourlyEmployee) { ((HourlyEmployee) employee).setHoursWorkedThisQuarter(empIdToHoursWorked.get(employee.getId())); } totalCost += employee.calculatePay(); } } return totalCost; } }
Go Company Module
package collections var ( // (A) Create a map to hold employee id to hours worked this quarter empIdToHoursWorked map[int64]float64 = make(map[int64]float64) // (B) Create a map to hold employee id to sales this quarter empIdToSales map[int64]float64 = make(map[int64]float64) // (B.1) list of departments departments []*Department = make([]*Department, 0, 10) // (B.2) map of department names to departments deptNameToDepartment map[string]*Department = make(map[string]*Department) ) func init() { //(C) declare four departments sales := NewDepartment("sales", NewSalesEmployee(3, "Whitney", "Hightower", 17, true, 0.05), NewSalesEmployee(60, "Alexander", "Hightower", 17, true, 0.05)) engineering := NewDepartment("engineering", NewEmployee(1, "Rick", "Hightower", 32, true), NewHourlyEmployee(2, "Bob", "Hightower", 27, true, 25.0)) hr := NewDepartment("hr", NewEmployee(10, "Diana", "Hightower", 32, true), NewHourlyEmployee(20, "Martha", "Hightower", 27, true, 25.0), NewHourlyEmployee(30, "Daniella", "Hightower", 27, true, 25.0)) manufacturing := NewDepartment("manufacturing", NewEmployee(40, "Joeseph", "Hightower", 32, true), NewHourlyEmployee(50, "John", "Hightower", 27, true, 25.0)) // (D) Bob worked 1750 hours this quarter. Martha and Daneilla each worked 350. How many did John work? empIdToHoursWorked[2] = 1750.0 empIdToHoursWorked[30] = 350.0 empIdToHoursWorked[20] = 350.0 empIdToHoursWorked[50] = 350.0 // (E) Whitney is our best sales person, but Alexander did good for a three year old. empIdToSales[60] = 5000000 empIdToSales[3] = 1000000 // (F) Add the three departments to the list of departments departments = append(departments, engineering, hr, manufacturing, sales) // (G) add some department to name mappings deptNameToDepartment[engineering.Name()] = engineering deptNameToDepartment[hr.Name()] = hr deptNameToDepartment[manufacturing.Name()] = manufacturing deptNameToDepartment[sales.Name()] = sales } // (H) Calculate Employee Cost func CalculateCompanyEmployeeCost() float64 { totalCost := 0.0 //Nested for loop, looping over employees in each department. for _, department := range departments { for _, employee := range department.Employees() { switch employee.(type) { case SalesEmployee: employee.(SalesEmployee).SetQuarterlySales(empIdToSales[employee.Id()]) case HourlyEmployee: employee.(HourlyEmployee).SetHoursWorkedThisQuarter(empIdToHoursWorked[employee.Id()]) } totalCost += employee.CalculatePay() } } return totalCost }Now the employees
Java Employees
package com.example.collections; public class Employee { protected long id; protected String firstName; protected String lastName; protected int age; protected boolean current; public Employee(long id, String firstName, String lastName, int age, boolean current) { this.firstName = firstName; this.lastName = lastName; this.age = age; this.current = current; this.id = id; } public double calculatePay() { return 0.0d; } public String name() { return this.firstName + " " + this.lastName; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public long getId() { return id; } public boolean isCurrent() { return current; } public void setLastName(String lastName) { this.lastName = lastName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setAge(int age) { this.age = age; } public void setCurrent(boolean current) { this.current = current; } } package com.example.collections; public class HourlyEmployee extends Employee { private double hourlyRate; private transient double hoursWorkedThisQuarter; public HourlyEmployee(Long id, String firstName, String lastName, int age, boolean current, double commisionRate) { super(id, firstName, lastName, age, current); this.hourlyRate = commisionRate; } public double calculatePay() { return this.hourlyRate * hoursWorkedThisQuarter; //lookup hours worked in DB, but for this just hard code } public double getHourlyRate() { return hourlyRate; } public void setHourlyRate(double hourlyRate) { this.hourlyRate = hourlyRate; } public void setHoursWorkedThisQuarter(double hoursWorkedThisQuarter) { this.hoursWorkedThisQuarter = hoursWorkedThisQuarter; } } package com.example.collections; public class SalesEmployee extends Employee { private double commisionRate; private transient double quarterlySales = -1; public SalesEmployee(Long id, String firstName, String lastName, int age, boolean current, double commisionRate) { super(id, firstName, lastName, age, current); this.commisionRate = commisionRate; } public double calculatePay() { if (quarterlySales == -1) { throw new RuntimeException("quarterly sales not set"); } return this.commisionRate * quarterlySales; } public double getCommisionRate() { return commisionRate; } public void setCommisionRate(double commisionRate) { this.commisionRate = commisionRate; } public void setQuarterlySales(double sales) { this.quarterlySales = sales; } }Now the Go Employees
package collections type Employee interface { CalculatePay() float64 Name() string Id() int64 } type EmployeeImpl struct { id int64 firstName string lastName string age int current bool } func (this *EmployeeImpl) CalculatePay() float64 { return 0.0 } func (this *EmployeeImpl) Name() string { return this.firstName + " " + this.lastName } func NewEmployee(id int64, firstName string, lastName string, age int, current bool) *EmployeeImpl { return &EmployeeImpl{id, firstName, lastName, age, current} } func (this *EmployeeImpl) FirstName() string { return this.firstName } func (this *EmployeeImpl) LastName() string { return this.lastName } func (this *EmployeeImpl) Age() int { return this.age } func (this *EmployeeImpl) Id() int64 { return this.id } func (this *EmployeeImpl) Current() bool { return this.current } func (this *EmployeeImpl) SetFirstName(name string) { this.firstName = name } func (this *EmployeeImpl) SetLastName(name string) { this.lastName = name } func (this *EmployeeImpl) SetAge(newAge int) { this.age = newAge } func (this *EmployeeImpl) SetCurrent(current bool) { this.current = current } func (this *SalesEmployeeImpl) SetHoursWorkedThisQuarter(sales float64) { this.quarterlySales = sales } package collections type HourlyEmployee interface { Employee SetHoursWorkedThisQuarter(rate float64) } type HourlyEmployeeImpl struct { EmployeeImpl //HourlyEmployee extends Employee by using this anonymous field hourlyRate float64 hoursThisQuarter float64 } func NewHourlyEmployee(id int64, firstName string, lastName string, age int, current bool, hourlyRate float64) *HourlyEmployeeImpl { return &HourlyEmployeeImpl{EmployeeImpl{id, firstName, lastName, age, current}, hourlyRate, 0.0} } func (this *HourlyEmployeeImpl) CalculatePay() float64 { return this.hourlyRate * this.hoursThisQuarter } func (this *HourlyEmployeeImpl) HourlyRate() float64 { return this.hourlyRate } func (this *HourlyEmployeeImpl) SetHourlyRate(rate float64) { this.hourlyRate = rate } func (this *HourlyEmployeeImpl) SetHoursWorkedThisQuarter(rate float64) { this.hoursThisQuarter = rate } package collections type SalesEmployee interface { Employee SetQuarterlySales(rate float64) } type SalesEmployeeImpl struct { EmployeeImpl //Sales extends Employee by using this anonymous field commisionRate float64 quarterlySales float64 } func (this *SalesEmployeeImpl) CalculatePay() float64 { return this.commisionRate * this.quarterlySales } func NewSalesEmployee(id int64, firstName string, lastName string, age int, current bool, commisionRate float64) *SalesEmployeeImpl { return &SalesEmployeeImpl{EmployeeImpl{id, firstName, lastName, age, current}, commisionRate, 0.0} } func (this *SalesEmployeeImpl) CommisionRate() float64 { return this.commisionRate } func (this *SalesEmployeeImpl) SetCommisionRate(rate float64) { this.commisionRate = rate } func (this *SalesEmployeeImpl) SetQuarterlySales(sales float64) { this.quarterlySales = sales }Now the main method that call them both.
In Java...
package com.example; import com.example.collections.Company; public class UseCollection { public static void main(String[] args) { System.out.printf("Money spent on employees for last quarter %2.2f \n", Company.calculateCompanyEmployeeCost()); } }
In Go...
package main import ( "example/collections" "fmt" ) func main() { fmt.Printf("Money spent on employees for last quarter %2.2f \n", collections.CalculateCompanyEmployeeCost()); }