sorting objects from different classes java - java

I hava below task. I stuck on the problem a).
Create classes, which describe employees with hourly wage and fixed payment. Give your suggestions
about relations between classes. Implement method for calculating the average monthly salary. For
employees with hourly wage use next formula: “average monthly salary= 20.8*8* hourly rate”, for employees
with fixed payment – “average monthly salary= fixed monthly payment”. Write well commented code for
solving next problems
a) Sort the collection of employees in descending order by the average monthly salary. In the case of
equal salary – by the name. Write ID, name and monthly salary for all employees from collection.
b) Write information about first five employees from collection (problem a).
c) Write ID of three last employees from collection (problem b).
d) Write code for reading and writing collection of these objects from (into) file.
e) Write code for handling the incorrect format of incoming file.
I have created below classes, but I have no idea how to sort different objects from different classes. Please help me!!!!
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<EmployeeFixedPayment> coll = new ArrayList<Employee>();
EmployeeHourlyWage a = new EmployeeHourlyWage("Edd", "Goo", 23, 4);
EmployeeHourlyWage b = new EmployeeHourlyWage("Tedd", "Foo", 2, 5);
EmployeeHourlyWage c = new EmployeeHourlyWage("Bob", "Bee", 4, 2);
EmployeeHourlyWage d = new EmployeeHourlyWage("Kate", "See", 2, 5);
EmployeeFixedPayment e = new EmployeeFixedPayment("Lisa", "Lee", 7, 500);
EmployeeFixedPayment f = new EmployeeFixedPayment("Mike", "Ree", 10,
450);
EmployeeFixedPayment g = new EmployeeFixedPayment("Izia", "Kurz", 13,
1000);
EmployeeFixedPayment j = new EmployeeFixedPayment("Aisha", "Moore", 20,
800);
coll.add(a);
coll.add(b);
coll.add(c);
coll.add(d);
coll.add(e);
coll.add(f);
coll.add(g);
coll.add(j);
Collections.sort(coll);
// System.out.println(coll.size());
for (Employee i : coll) {
System.out.print(i.secondName + " ");
}
}
}
public class Employee {
String firstName;
String secondName;
int id;
public Employee(String firstName, String secondName,int id){
this.firstName = firstName;
this.secondName = secondName;
this.id = id;
}
public void printEmployee(){
System.out.println(firstName+" "+secondName+" "+id);
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
}
public class EmployeeFixedPayment extends Employee {
double fixedPayment;
public EmployeeFixedPayment(String firstName, String secondName, int id,
double salary) {
super(firstName, secondName, id);
fixedPayment = salary;
}
public double getSalary() {
return fixedPayment;
}
public void setSalary(double salary) {
fixedPayment = salary;
}
}
public class EmployeeHourlyWage extends Employee {
Double hourlyWage;
public EmployeeHourlyWage(String firstName, String secondName, int id, double hourlyRate) {
super(firstName, secondName, id);
hourlyWage = 20.8*8*hourlyRate;
}
public double getWage(){
return hourlyWage;
}
public void setWage(double rate) {
hourlyWage = 20.8*8*rate;
}
}

Implement the Comparable interface for Employee. This way they get sortet the right way when you call Collections.sort(coll) .
Personally I find the CompareToBuilder class helpfull for this.

The trick here is to pull the relevant information (i.e., the monthly salary) up to a base class (Employee), so you can write a Comparator for it.
So first, let's pull the relevant method up to Employee. Since Employee does not contain the logic to calculate its salary, that'd make the class abstract:
public abstract class Employee {
public abstract double getMonthlySalary();
// Rest of the members and methods you declared
}
public class EmployeeFixedPayment extends Employee {
double fixedPayment;
#Override
public double getMonthlySalary() {
return fixedPayment;
}
// Rest of the members, ctots, etc. you declared
}
public class EmployeeHourlyWage extends Employee {
double hourlyWage;
#Override
public double getMonthlySalary() {
return hourlyWage * 20.8 * 8;
}
// Rest of the members, ctots, etc. you declared
}
Now that all Employees expose their salary in a coherent interface, they can be sorted by implementing a Comparator:
public class EmployeeComparator implements Comparator<Employee> {
#Override
public int compare (Employee e1, Employee e2) {
// Note we're comparing e2 to e1 to get a descneding effect
int salaryCompare = Double.compare(e2.getMonthlySalary(), e1.getMonthlySalary());
if (salaryCompare != 0) {
return salaryCompare;
}
// If the salaries are equal, compare names
return e1.getName().compareTo(e2.getName());
}
}
Now, to put it all together, we just sort the List with our custom Comparator:
List<Employee> coll = new ArrayList<>();
Collections.sort(coll, new EmployeeComparator());

Related

How to get top 3 records in ArrayList<Employee> with java OPP?

I have 2 files a.txt and b.txt.
a.txt has 3 columns: id, name and month
e1,David,12
e2,Jane,24 e4,Peter,15 e3,John,25 ...
b.txt has 2 columns: id and baseSalary
e1,1200e2,1800e4,2400
...
I will read a.txt to an ArrayList.
public ArrayList<Employee> loadEmployee(String file) {
ArrayList<Employee> Emp = new ArrayList<Employee>();
ArrayList<String> employees = loadFile(file);
for (String emp : employees) {
String[] data = emp.split(",");
Emp.add(new Employee(data[0], data[1], Integer.parseInt(data[2])));
}
return Emp;
}
public class Employee{
private String id;
private String name;
private int month;
public Employee(String id, String name, int month){
this.id=id;
this.name=name;
this.month=month;
}
public double getSalary(int baseSalary){
return this.month*baseSalary;
}
public String toString(){
return this.id+"_"+this.name+"_"+this.month;
}
}
Now I want to get top 3 employee has highest salary.But you cannot create new class.
I don't know how to do. I'm new in java OPP. I think I will read b.txt to a hashmap, but hashmap cannot sort. So I cannot get top 3.
Anyone can help me?
Sorry if my English is not good.
Your loadEmployee method is a good start, but as you said you have to read the second file to get the base salary for each employee and compute their overall salary (I guess it's a total income).
You could define a second method, setEmployeeBaseSalary, which accepts the second file's name and the List of employees. Then, you basically read the second file in the same way you've done with the first one. For each id read, you perform a search through your List, gather the employee by its id and then set its base salary.
After updating your List of employees, you could use the collection stream to sort your list by salary, gather the first three results and then collect them into a new List.
public static ArrayList<Employee> loadEmployee(String file) {
//your exact same implementation
}
public static ArrayList<Employee> setEmployeeBaseSalary(String file, List<Employee> list) {
ArrayList<Employee> Emp = new ArrayList<>();
try (FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr)) {
Employee emp;
String line = br.readLine();
while (line != null) {
String[] data = line.split(",");
//Looking for an employee by the id read
emp = list.stream().filter(employee -> employee.getId().equals(data[0])).findFirst().orElse(null);
//If an employee with that id has been found then it's base salary is set
if (emp != null) {
emp.setBaseSalary(Double.parseDouble(data[1]));
}
line = br.readLine();
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
return Emp;
}
Test main
public static void main(String[] args) {
//Reading the list of employees
ArrayList<Employee> listEmployee = loadEmployee("a.txt");
//Setting the base salary for each employee
setEmployeeBaseSalary("b.txt", listEmployee);
//Retrieving the top three salary employees
List<Employee> listTopThreeEmployee = listEmployee.stream()
.sorted(Comparator.comparingDouble(Employee::getSalary).reversed()) //sorting each employee by their salary in reversed order (from the highest to the lowest)
.limit(3) //Limiting the stream to the top three results
.collect(Collectors.toList()); //Collecting the top three employees in a new list
System.out.println(listTopThreeEmployee);
}
In addition, you should add within your Employee class setter and getter methods to set up and retrieve the Employee's fields.
class Employee {
private String id;
private String name;
private int month;
private double baseSalary;
public Employee(String id, String name, int month) {
this.id = id;
this.name = name;
this.month = month;
this.baseSalary = 0;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public double getBaseSalary() {
return baseSalary;
}
public void setBaseSalary(double baseSalary) {
this.baseSalary = baseSalary;
}
public double getSalary() {
return this.month * this.baseSalary;
}
public String toString() {
return "(" + this.id + "-" + this.name + "-" + this.month + "-" + baseSalary + "-" + getSalary() + ")";
}
}
On a side note: variables representing currency should be declared as BigDecimal rather than double, as it is important to have an exact representation of the value rather than an approximation. In fact, the double precision tries to represent the value as closely as possible, but it's not said that it corresponds to the actual value assigned.

I need to get the max from a Employee class from a Farm class

I need to find and display the the employee who has the maximum salary from the Farm.
this is what I got so far
public class Employee implements Comparable<Employee> {
private String name;
private Integer salary;
public Employee (String name , Integer salary) {
this.name = name;
this.salary = salary;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public Integer getSalary() {
return salary;
}
public String toString() {
return name + " " + salary;
}
public int compareTo(Employee emp) {
return this.salary.compareTo(emp.getSalary());
}
}
Employee class
public class Farm {
private String name;
private Integer surface;
List<Employee> emp = new ArrayList<Employee>();
public Farm(String name , Integer surface) {
this.name = name;
this.surface = surface;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSurface(Integer surface) {
this.surface = surface;
}
public int getSurface () {
return surface;
}
public String toString() {
return name + " " + surface;
}
public void makeList(String ename , Integer esalary) {
this.emp.add(new Employee(ename,esalary));
}
public void getList() {
for(Employee el : emp)
System.out.println(el);
}
}
And the last one is the main. The thing is that I don't know how can I have more farms and get the max from every single one of them. Can you guys help me?
And this is my mainapp
public class Mainapp {
public static void main(String args[])
{
List <Farm> FarmList = new ArrayList<Farm>();
FarmList.add(new Farm("unirea pizdii", 890030));
FarmList.add(new Farm("pseudo autsm",78594));
FarmList.add(new Farm("haha hihi",854856099));
Farm farm1 = new Farm("Tiguana" , 700);
farm1.makeList("Mihai", 30000);
farm1.makeList("Vladimir", 4000);
farm1.makeList("Tusnic", 3000);
farm1.getList();
Employee emp1 = new Employee(" mihai", 3000);
System.out.println(emp1);
}
}
To get employee with max salary for each farm you can use stream api:
import static java.util.stream.Collectors.*;
Map<Farm, Optional<Employee>> collect =
farmList.stream().collect(groupingBy(Function.identity(),
flatMapping(farm -> farm.getEmployes().stream(),
maxBy(Employee::compareTo))));
Result map has Farm as a key and Employee with max salary as a value
Note: flatMapping method is from java9
There are multiple ways to sort a List in Java, one of them being Collections.sort(List), but in this case it looks like you are trying to retrieve the maximum value from the list, so there's no need to add the extra overhead.
EDIT: JB Nizet suggested using Collections.max(List):
public Employee getMostPaidEmployee() {
return Collections.max(emp);
}
One way to get the most paid employee from the list would be to loop through them and compare each one to the previously "saved" most paid employee:
// Farm.java
public Employee getMostPaidEmployee() {
Employee mostPaid = null;
// Initialize maximum to the lowest possible value.
// If salaries can only be positive you could also initialize this to `0`.
int maximumSalary = Integer.MIN_VALUE;
for (Employee employee : emp) {
if (employee.getSalary() > maximumSalary) {
// Reset the most paid fields
mostPaid = employee;
maximumSalary = employee.getSalary();
}
}
return mostPaid;
}
You can declare this method on the Farm class, so you will be able to call it even if you have multiple instances of Farm:
List<Farm> farms = new ArrayList<>();
// TODO Add farms
// Get the most paid employee in first farm
Employee mostPaid = farms.get(0).getMostPaidEmployee();
In terms of performance, this method is linear, i.e. O(n).

How to add new Employee without declaring a lot of object names

I have a small assignment on adding and displaying different types of employees(diff. departments) at work and different salary & benefits, using OOP approach. I am quite not sure if my code is correct in terms of code reuse & if did I really meet the OOP coding approach...So far I have displayed 1 employee each type/department, I made them as a class name.(see code below). My question is if I add a new employee I'm going to declare another object of type Employee again. And what if there will be a lot of employees, I will be having a lot of objects. How do I lessen that and may I know if my OOP coding approach is correct so far? Ty very much! Here is my code:
//this is my parent class which implements an interface...
public abstract class Employees implements ICompensation{
private String fname;
private String lname;
private char gender;
private String address;
private double salary;
public String getfname(){
return this.fname;
}
public void setfname(String fname){
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
// this is a Developer type of employee
public class Developer extends Employees{
public Developer(String fname,String lname, char gender,String address, double salary){
setfname(fname);
setLname(lname);
setGender(gender);
setAddress(address);
setSalary(salary);
}
#Override
public double calculateSalary() {
double salary = getSalary();
salary += 10;
return salary;
}
#Override
public void print() {
System.out.println(this.getClass());
System.out.println(this.getfname());
System.out.println(this.getLname());
System.out.println(this.getGender());
System.out.println(this.getAddress());
System.out.println(this.calculateSalary());}}
//this is QA type of employee
public class QA extends Employees{
public QA(String fname,String lname,char gender,String address,double salary) {
setfname(fname);
setLname(lname);
setGender(gender);
setAddress(address);
setSalary(salary);
}
#Override
public double calculateSalary() {
double salary = getSalary();
salary = salary + 20;
return salary;
}
#Override
public void print() {
System.out.println(this.getClass());
System.out.println(this.getfname());
System.out.println(this.getLname());
System.out.println(this.getGender());
System.out.println(this.getAddress());
System.out.println(this.calculateSalary());
}
}
I have another 2 classes which are BA & Manager class but I wont include here because it's just have the same contents to the other derived class.
//so here is my Interface
public interface ICompensation {
double calculateSalary();
void print();
}
//and here is my main method.
import java.util.*;
public class main {
public static void main(String[] args){
Employees dev = new Developer("Janel","Logrono",'M',"Alabang",491);
Employees qa = new QA("juan","Sir",'M',"Taguig",1240);
Employees ba = new BA("pedro","Lyn",'F',"Taguig",1150);
Employees manager = new Manager("sebastian","rods",'M',"USA",555399);
ArrayList<Employees> ls = new ArrayList<>();
ls.add(dev);
ls.add(qa);
ls.add(ba);
ls.add(manager);
for(Employees e : ls){
e.print();
System.out.println();
}
}
}
How do add another employee w/o declaring a lot of objects and may I know if my OOP coding approach is correct so far, I think there are a lot of redundant codes here, how to lessen it? thx!
First of all you should not implements ICompensation in the bean class. Bean class will only contain getters, setters & constructor. You need to create another class which will implement the ICompensation. There you will write the code for calculations and other methods.
In database you can add another column "Role" which will define the employee role. By this approach you don't need to create extra methods such as QA, Developer, Manager.
please look into the following link. Here they tried to develop a login page using MVC model. You can just ignore the jsp pages and concentrate on controllers and beans.
https://krazytech.com/programs/a-login-application-in-java-using-model-view-controllermvc-design-pattern

From UML to Java, Simple association

This is the Image that I'm going to transfer from UML to Java, I don't know how to lock them together and i don't know how to make one bankAccount locked to only one person.
How do i connect the 2 classes??
Here is my code so far
My main method
public class Upp5 {
public static void main(String[] args) {
Person2 david = new Person2();
BankAccount acc1 = new BankAccount();
BankAccount acc2 = new BankAccount();
david.setName("David");
david.setPnr("551012-8978");
acc1.setBnr("37");
acc2.setBnr("38");
System.out.println("Namn: " + david.getName() + " \nPersonnummer:" + david.getPnr());
System.out.println(acc1.getBnr() + "\n" + acc2.getBnr());
}
}
BankAccount.java:
public class BankAccount {
private String bnr;
private double balance;
public void credit() {
}
public void withdraw(){
}
public String getBnr(){
return bnr;
}
public void setBnr(String newAccount){
bnr = newAccount;
}
public void createAccount(String newNbr){
bnr = newNbr;
}
}
and Person2.java
public class Person2 {
private String pnr;
private String name;
//Koppla konto till pnr
public void addAccount(BankAccount a){
}
//Skapa Pnr och Namn
public void setPnr(String newPnr) {
pnr = newPnr;
}
public void setName(String newName){
name = newName;
}
// Hämta Pnr och Namn
public String getPnr(){
return pnr;
}
public String getName(){
return name;
}
}
You need to define a List<BankAccount> to your Person2 entity:
public class Person2 {
private String pnr;
private String name;
// list of bank accounts (from 0 to n) the Person can have.
private List<BankAccount> accounts;
//Koppla konto till pnr
public void addAccount(BankAccount a){
if (accounts = null) accounts = new ArrayList<BankAccount>();
accounts.add(a);
}
//Skapa Pnr och Namn
public void setPnr(String newPnr) {
pnr = newPnr;
}
public void setName(String newName){
name = newName;
}
// Hämta Pnr och Namn
public String getPnr(){
return pnr;
}
public String getName(){
return name;
}
// include getters setters
}
EDIT1: as suggested by #NathanCastlehow if you want double relationship, BankAccount.java must have a Person2 attibute
public class BankAccount {
private String bnr;
private double balance;
// one bank account can only be owned by a single Person
private Person2 person;
public void credit() {
}
public void withdraw(){
}
public String getBnr(){
return bnr;
}
public void setBnr(String newAccount){
bnr = newAccount;
}
// generate getters setters
public Person2 getPerson(){
......
}
}
You didn't put any arrows in your diagram, so we don't know if the bankaccount knows the person it is linked to. The most logical thing to do is; let the Person have a List which you always initiate in the Person's constructor.
If you want the bankaccount to know the person that owns him (which seems logical to me), let the Bankaccount have the property "Person owner" and let the constructor be require a Person to exist. I don't understand why you have made a Person2 instead of a Person class.
Tips for you: Never (!!!) use parameters like; 'a' or properties like 'nBr' because other people wanna see in an instance what they are instead of guessing. :-) And try to make some security rules (that's why I put booleans in the classes).
Solution:
Person:
public class Person {
List<BankAccount> bankAccounts;
private String name;
private String pNbr;
public Person(String name, String pNbr) {
this.name = name;
this.pNbr = pNbr;
}
public void addAccount(BankAccount newAccount){
bankAccounts.Add(newAccount);
}
}
Bankaccount:
public class BankAccount {
private String nBr; //maybe make this final?
private double balance;
private Person owner;
public BankAccount(String nbr, Person owner) {
this(nbr, 0, owner); // If you also want to support new empty accounts
}
public BankAccount(String nbr, double balance, Person owner) {
this.name = name;
this.pNbr = pNbr;
this.owner = owner;
}
public boolean Credit(double amount)
{ // TODO: write code
boolean result = false;
return result;
}
public boolean Withdraw(double amount)
{ // TODO: write code
boolean result = false;
return result;
}
}
So generally when this is done in models such as a relational model you would have an association class. So a class that has like an ID from a bank account and an ID of the person. You can lock variables using the final keyword in front of them which forces them to only be initialized once.
The easiest way to "link" classes in java is to add one of said classes as an attribute. For example:
// Make it private to maintain encapsulation
private BankAccount myBankAccount;
But this only works if you have a 1..1 (One to one) relationship.
Your UML diagram indicates a 1..n (One to many) relationship between Person and BankAccount classes. In other words,
A Person may have multiple BankAccounts.
This means you'll a have to use a structure to "keep" multiple BankAccounts in a single Person. Java already provides you with some handy classes:
ArrayList: Easy, quick, insertion-ordered list. Allows as many itens as you need.
Hashmap: Hash implementation of the Map interface. Provides a way to find itens using a "key" (Ex: An account's number). Very efficient.
A suggest reading some of those classes documentation. And you can always look for some neat examples on the internet ;)

How to use Java comparator properly?

If I have the following class:
public class Employee {
private int empId;
private String name;
private int age;
public Employee(int empId, String name, int age) {
// set values on attributes
}
// getters & setters
}
How can I use comparator that compares by name, then age, then id?
You need to implement it so that it orders by preferred elements. That is, you need to compare by name, then if that comparison is equal, compare by age, etc. An example is listed below:
public class EmployeeComparator implements Comparator<Employee> {
#Override
public int compare(Employee e1, Employee e2) {
int nameDiff = e1.getName().compareTo(e2.getName());
if(nameDiff != 0) {
return nameDiff;
}
int ageDiff = e1.getAge() - e2.getAge();
if(ageDiff != 0) {
return ageDiff;
}
int idDiff = e1.getEmpId() - e2.getEmpId();
return idDiff;
}
}
Update
Came across this a moment ago: How to compare objects by multiple fields One of the answers linked to ComparatorChain which will invoke multiple comparators in sequence until a non-zero result is received from a comparator or all comparators are invoked. This should probably be your preferred solution.
Perhaps this (untested) implementation of Comparator#compare() will do the trick.
int compare(Employee e, Employee f)
{
int val = e.name.compareTo(f.name);
if(val == 0)
{
val = e.age - f.age;
if(val == 0)
{
val = e.empId - f.empId;
}
}
return val;
}
You can also implement the Comparable Interface in your class.
for example, something like this:
public class Employee implements Comparable<Employee>{
private int empId;
private String name;
private int age;
public Employee(int empId, String name, int age) {
// set values on attributes
}
// getters & setters
public int compareTo(Employee o) {
int ret = this.name.compareTo(o.name);
if(ret == 0)
ret = this.age - o.age;
if(ret == 0)
ret = this.empId - o.empId;
return ret;
}
}
so you don't have to implement a extra class to compare your Employees.
Implement it
public class Employee {
private int empId;
private String name;
private int age;
/**
* #param empId
* #param name
* #param age
*/
public Employee(int empId, String name, int age) {
super();
this.empId = empId;
this.name = name;
this.age = age;
}
/**
*
*/
public Employee() {
super();
// TODO Auto-generated constructor stub
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//Compare by name, age and then id
public static Comparator<Employee> COMPARE_EMPLOYEE = new Comparator<Employee>() {
public int compare(Employee one, Employee other) {
//Compare Name
if (one.getName().compareToIgnoreCase(other.getName()) == 0) {
//Compare age
if((one.getAge() - other.getAge()) == 0) {
// Now check with id is useless
// So directly return result of compare by id
return one.getEmpId() - other.getEmpId();
} else { //If age Not equal
return one.getAge() - other.getAge();
}
} else { //If name not equal
return one.getName().compareToIgnoreCase(other.getName());
}
}
};
}
Use :
List<Employee> contacts = new ArrayList<Employee>();
//Fill it.
//Sort by address.
Collections.sort(contacts, Employee.COMPARE_EMPLOYEE);
Read Sorting an ArrayList of Contacts , this must help you and you will get more ideas and different different types of use of Comparator.
guava ComparisonChain:
List<Employee> list = new ArrayList<Employee>();
//...
Collections.sort(list, new Comparator<Employee>(){
#Override
public int compare(Employee e1, Employee e2) {
return ComparisonChain.start()
.compare(e1.empId, e2.empId)
.compare(e1.name, e2.name)
.compare(e1.age, e2.age).result();
}});
Use this:
public class Test
{
public static void main(String[] args)
{
Employee emp1 = new Employee(2, "Tom", 20);
Employee emp2 = new Employee(1, "Tom", 20);
Employee emp3 = new Employee(3, "Hank", 21);
List<Employee> list = new ArrayList<>();
list.add(emp1);
list.add(emp2);
list.add(emp3);
Collections.sort(list, new Employee().new MyComparator());
System.out.println(list);
}
}
class Employee
{
private int empId;
private String name;
private int age;
public Employee()
{}
public Employee(int empId, String name, int age)
{
this.empId = empId;
this.name = name;
this.age = age;
}
class MyComparator implements Comparator<Employee>
{
#Override
public int compare(Employee e1, Employee e2)
{
if(e1.name.compareTo(e2.name) == 0)
{
if(((Integer)e1.age).compareTo(e2.age) == 0)
{
return ((Integer)e1.empId).compareTo(e2.empId);
}
else
{
return ((Integer)e1.age).compareTo(e2.age);
}
}
return e1.name.compareTo(e2.name);
}
}
#Override
public String toString()
{
return "Employee [empId=" + empId + ", name=" + name + ", age=" + age + "]";
}
}
The Comparator interface defines two methods: compare() and equals().
The compare() method, compares two elements for order:
int compare(Object obj1, Object obj2)
obj1 and obj2 are the objects to be compared. This method returns zero if the objects are equal. It returns a positive value if obj1 is greater than obj2. Otherwise, a negative value is returned.
By overriding compare(), you can alter the way that objects are ordered. For example, to sort in a reverse order, you can create a comparator that reverses the outcome of a comparison.
The equals() method, tests whether an object equals the invoking comparator: boolean equals(Object obj)
obj is the object to be tested for equality. The method returns true if obj and the invoking object are both Comparator objects and use the same ordering. Otherwise, it returns false.
Example:
import java.util.*;
class Dog implements Comparator<Dog>, Comparable<Dog> {
private String name;
private int age;
Dog() {
}
Dog(String n, int a) {
name = n;
age = a;
}
public String getDogName() {
return name;
}
public int getDogAge() {
return age;
}
// Overriding the compareTo method
public int compareTo(Dog d) {
return (this.name).compareTo(d.name);
}
// Overriding the compare method to sort the age
public int compare(Dog d, Dog d1) {
return d.age - d1.age;
}
}
public class Example {
public static void main(String args[]) {
// Takes a list o Dog objects
List<Dog> list = new ArrayList<Dog>();
list.add(new Dog("Shaggy", 3));
list.add(new Dog("Lacy", 2));
list.add(new Dog("Roger", 10));
list.add(new Dog("Tommy", 4));
list.add(new Dog("Tammy", 1));
Collections.sort(list); // Sorts the array list
for(Dog a: list) // printing the sorted list of names
System.out.print(a.getDogName() + ", ");
// Sorts the array list using comparator
Collections.sort(list, new Dog());
System.out.println(" ");
for(Dog a: list) // printing the sorted list of ages
System.out.print(a.getDogName() +" : "+ a.getDogAge() + ", ");
}
}
Check it out for more Java Comparator examples.

Categories

Resources