I am new to using HazelCast. I have a map of key and value, value being a list of objects. I am trying to use SqlPredicate on the map to filter the values.
Code Snippet:
private void testHazelCast() {
final Employee e1 = new Employee("A", 20, 30);
final Employee e2 = new Employee("C", 25, 45);
final Employee e3 = new Employee("B", 30, 35);
final Employee e4 = new Employee("F", 35, 30);
final Employee e5 = new Employee("E", 40, 40);
final Employee e6 = new Employee(null, 40, 20);
final Employee e7 = new Employee("F", 60, 55);
List<Employee> employeeList_1 = new ArrayList<Employee>() {{add(e1);add(e2);}};
List<Employee> employeeList_2 = new ArrayList<Employee>() {{add(e3);add(e4);add(e7);}};
List<Employee> employeeList_3 = new ArrayList<Employee>() {{add(e5);}};
List<Employee> employeeList_4 = new ArrayList<Employee>() {{add(e6);}};
IMap<Integer, List<Employee>> map = hazelcast.getMap("employee");
map.put(1, employeeList_1);
map.put(2, employeeList_2);
map.put(3, employeeList_3);
map.put(4, employeeList_4);
// EntryObject e = new PredicateBuilder().getEntryObject();
// Predicate predicate_1 = e.get("name").equal("A");
Predicate predicate = new SqlPredicate("name = A");
Set<List<Employee>> employeeSet = (Set<List<Employee>>) map.values(predicate_1);
}
class Employee implements Serializable {
String name;
int age;
int weight;
public Employee(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Name: " + name + ", ");
sb.append("Age: " + age + ", ");
sb.append("Weight: " + weight);
return sb.toString();
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
if (age != employee.age) return false;
if (weight != employee.weight) return false;
if (!name.equals(employee.name)) return false;
return true;
}
#Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age;
result = 31 * result + weight;
return result;
}
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;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
While executing the above code, I am getting an exception:
Caused by: java.lang.IllegalArgumentException: There is no suitable accessor for 'name' on class 'class java.util.ArrayList'
Could you somebody let me know what exactly I am doing wrong. I understand that it's trying to find the "name" element in the List class.
Is there anyway that I can use SqlPredicate to filter the values ?
Thanks,
Rahul
A predicat is executed on each value of a map. In your example, your map has a Collection of Employee as values, so the predicat is executed on this collection.
Your predicat evaluate to "a collection with name = A" : This is not valid, because a collection doesn't have a name.
In Hazelcast 3.6, you have a notion of 'custom attribute' and ValueExtractor. You can :
Create a class, which own a collection of employee
Link this class to a ValueExtractor which collect the names of each employe in a custom attribute 'name'
see: http://docs.hazelcast.org/docs/3.6/manual/html-single/index.html#custom-attributes
Moreover, having a map of collection is not very efficient.
Related
Adding array of object into array list and compare with other array list based on one property value and filter the result.
I have an array of object personDetails and departmentDetails.
package com.education;
import java.util.*;
public class educationMain {
public static void main(String[] args) {
List<person> list=new ArrayList<person>();
person l1 = new person(1,"Samual",100,"Sales","Business");
person l2 = new person(2,"Alex",100,"Sales","Business");
person l3 = new person(3,"Bob",101,"Engineering","Technology");
person l4 = new person(4,"Michel",101,"Engineering","Technology");
person l5 = new person(5,"Ryan",102,"PR","Services");
person l6 = new person(6,"Horward",103,"Leadership","Managmnet");
person l7 = new person(7,"Cyna",104,"HR","Human Resource");
list.add(l1);
list.add(l2);
list.add(l3);
list.add(l4);
list.add(l5);
list.add(l6);
list.add(l7);
for(person b:list){
System.out.println(b.personId+" "+b.name+" "+b.deptCode+" "+b.parentDept+" "+b.deptName);
}
List<department> depList = new ArrayList<department>();
department d1 = new department(100, "Sales","Business");
department d2 = new department(101, "Engineering","Technology");
department d3 = new department(102, "PR","Services");
depList.add(d1);
depList.add(d2);
depList.add(d3);
for(department b:depList){
System.out.println(b.deptCode+" "+b.parentDept+" "+b.deptName);
}
}
}
So above code is working fine and displaying correctly.
My person class
package com.education;
public class person {
public int personId;
public String name;
private int deptCode;
private String parentDept;
private String deptName;
public person(int personId, String name, int deptCode, String parentDept, String deptName) {
super();
this.personId = personId;
this.name = name;
this.deptCode = deptCode;
this.parentDept = parentDept;
this.deptName = deptName;
}
public void display(){
System.out.println(" " + personId + " " +name + " " + deptCode+ " " + parentDept + " "+deptName);
System.out.println();
}
}
My department class
public class department {
private int deptCode;
private String parentDept;
private String deptName;
public department(int deptCode, String parentDept, String deptName) {
super();
this.deptCode = deptCode;
this.parentDept = parentDept;
this.deptName = deptName;
}
public void dispalyDepartment() {
System.out.println(" "+deptCode+" "+parentDept+" "+deptName);
}
}
Now My goal is personDetails and departmentDetailsinto arraylist and compare and then findout the diference one bsed on dept code.
Here is my Logic : which is working fine.
List<person> listC = new ArrayList<person>();
for(person p : list) {
boolean flag = false;
for (department d:depList) {
if(p.deptCode == d.deptCode) {
flag = false;
break;
}else {
flag = true;
}
}
if(flag == true) {
listC.add(p);
}
}
o/p should be like
(6,"Horward",103,"Leadership","Managmnet");
(7,"Cyna",104,"HR","Human Resource");
because deptCode : 103 and 104 is not present.
Can anybody help me here. Can I use any other collection technique.
Try this.
Set<Integer> deptCodes = Arrays.stream(departmentDetails)
.map(department -> department.deptCode)
.collect(Collectors.toSet());
List<person> persons = Arrays.stream(personDetails)
.filter(person -> !deptCodes.contains(person.deptCode))
.collect(Collectors.toList());
persons.forEach(person -> person.display());
output:
6 Horward 103 Leadership Managmnet
7 Cyna 104 HR Human Resource
I am trying to print "name" of an employee from a list of employees. Below is my pojo class.
import java.time.LocalDate;
public class Employee {
private String name;
private String empID;
private Designation designation;
private LocalDate dateOfJoining;
private int monthlySalary;
public Employee(String name, String empID, Designation designation, LocalDate dateOfJoining, int monthlySalary) {
super();
this.name = name;
this.empID = empID;
this.designation = designation;
this.dateOfJoining = dateOfJoining;
this.monthlySalary = monthlySalary;
}
public Employee() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmpID() {
return empID;
}
public void setEmpID(String empID) {
this.empID = empID;
}
public Designation getDesignation() {
return designation;
}
public void setDesignation(Designation designation) {
this.designation = designation;
}
public LocalDate getDOJ() {
return dateOfJoining;
}
public void setDOJ(LocalDate dOJ) {
dateOfJoining = dOJ;
}
public int getMonthlySalary() {
return monthlySalary;
}
public void setMonthlySalary(int monthlySalary) {
this.monthlySalary = monthlySalary;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dateOfJoining == null) ? 0 : dateOfJoining.hashCode());
result = prime * result + ((designation == null) ? 0 : designation.hashCode());
result = prime * result + ((empID == null) ? 0 : empID.hashCode());
result = prime * result + monthlySalary;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (dateOfJoining == null) {
if (other.dateOfJoining != null)
return false;
} else if (!dateOfJoining.equals(other.dateOfJoining))
return false;
if (designation == null) {
if (other.designation != null)
return false;
} else if (!designation.equals(other.designation))
return false;
if (empID == null) {
if (other.empID != null)
return false;
} else if (!empID.equals(other.empID))
return false;
if (monthlySalary != other.monthlySalary)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return "Employee [name=" + name + ", empID=" + empID + ", designation=" + designation + ", DOJ=" + dateOfJoining
+ ", monthlySalary=" + monthlySalary + "]";
}
}
Now while I am trying to print the "name", I am getting null value.
Please see as below,
import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Employecomparable {
public static void main(String[] args) {
JoiningDate jd = new JoiningDate();
Employee emp = new Employee();
List<Employee> listofemployee = new ArrayList<>();
listofemployee.add(new Employee("abc", "12345", Designation.ASE,jd.date1 , 20000));
listofemployee.add(new Employee("abcd", "24680", Designation.SE, jd.date2, 30000));
listofemployee.add(new Employee("abcde", "13570", Designation.SSE,jd.date3, 40000));
listofemployee.add(new Employee("abcdef", "13690", Designation.TL, jd.date4, 60000));
listofemployee.add(new Employee("xyz", "10909", Designation.AM, jd.date5, 800000));
listofemployee.add(new Employee("koool", "89076", Designation.M, jd.date6, 2000));
System.out.println("The name of employee is "+emp.getName());
I am getting the output as "null".
In console I get, The name of employee is null.
How do i print the name?
Please help!
To print the name of a particular employee, kindly update the emp object.
emp = listofemployee.get(indexWithinTheList);
System.out.println("The name of employee is "+emp.getName());
Example:
emp = listofemployee.get(0);
System.out.println("The name of employee is "+emp.getName());
Output : The name of employee is abc
You may want to iterate over your employee and then print the name. Reason you get null is you created Employee object with default constructor. Which would mean name being string object would take default null value which is what you see.
If you want to print employee names, you could do the following:
for (Employee employee: listofemployee) {
System.out.println("The name of employee is " + employee.getName());
}
Since you are using List interface, you can access individual object by it's index. E.g. to get first employee name:
System.out.println("The name of employee is " + listofemployee.get(0).getName());
The error you are getting is because you have created the Employee object like below.
Employee emp = new Employee(); After that you are populating the list using new Employee. But you have not set any value to variable emp.so getName from emp will return null. If you want to get the value from emp. You first need to set the name using emp.SetName("Any name"); No you will get the value using emp.getName();
1 - Create Employee object like below:-
Employee emp =new Employee("xyz", "10909", Designation.AM, jd.date5,
800000);
2 - Then store into list.
3 - After that iterate over list and print result as per your requirement.
public static void main(String[] args) {
JoiningDate jd = new JoiningDate();
Employee emp = new Employee();
List<Employee> listofemployee = new ArrayList<>();
emp = new Employee("abc", "12345", Designation.ASE,jd.date1 , 20000);
listofemployee.add(emp);
emp =new Employee("abcd", "24680", Designation.SE, jd.date2, 30000);
listofemployee.add(emp);
emp =new Employee("abcde", "13570", Designation.SSE,jd.date3, 40000);
listofemployee.add(emp);
emp = new Employee("abcdef", "13690", Designation.TL, jd.date4, 60000);
listofemployee.add(emp);
emp =new Employee("koool", "89076", Designation.M, jd.date6, 2000);
listofemployee.add(emp);
emp =new Employee("xyz", "10909", Designation.AM, jd.date5, 800000);
listofemployee.add(emp);
System.out.println("The name of employee is "+emp.getName());
Iterator<Employee> itr = listofemployee.iterator();
// checking the next element availabilty
while (itr.hasNext())
{
System.out.println("name " + (itr.next()).getName());
}
}
For TreeSet Sorting for mutable object :
If I don't override hashcode equals then for an object having same value for all the fields will be treated as two different object in set as( default objects class hashcode method calculate the hash value of the memory locatuion). So why it is different for the TreeSet. See the below Example.
If I just copy a whole Set into a treeSet then why sorting is not happning.
.
public class Student {
private int id;
private String name;
private int marks;
public Student(int id, String name, int marks) {
super();
this.id = id;
this.name = name;
this.marks = marks;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", marks=" + marks + "]";
}
public static Comparator<Student> idComparator = new Comparator<Student>() {
#Override
public int compare(Student o1, Student o2) {
return (new Integer(o1.getId())).compareTo(o2.getId());
}
};
public static Comparator<Student> nameComparator = new Comparator<Student>() {
#Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
};
/*#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + marks;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (id != other.id)
return false;
if (marks != other.marks)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}*/
}
.
public class TestMain {
public static void main(String[] args) {
Student s1 = new Student(1, "A", 50);
Student s2 = new Student(1, "A", 50);
Student s3 = new Student(2, "B", 51);
Student s4 = new Student(3, "B", 51);
Student s5 = new Student(4, "B", 41);
Student s6 = new Student(5, "B", 61);
Student s7 = new Student(6, "C", 51);
Student s8 = new Student(7, "D", 46);
Student s9 = new Student(8, "B", 55);
Student s10 = new Student(9, "E", 51);
List<Student> studentList = new ArrayList<>();
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
studentList.add(s4);
studentList.add(s5);
studentList.add(s6);
studentList.add(s7);
studentList.add(s8);
studentList.add(s9);
studentList.add(s10);
studentList.add(s1);
studentList.add(s2);
studentList.add(s3);
studentList.add(s4);
System.out.println("List Initial Size: " + studentList.size());
List<Student> studentListAfterFilter = studentList.stream()
.filter(p -> p.getMarks() >= 45 && p.getMarks() <= 55).map(p -> p).collect(Collectors.toList());
System.out.println("After filtering List Size: " + studentListAfterFilter.size());
Set<Student> studentSetAfterFilter = studentList.stream().filter(p -> p.getMarks() >= 45 && p.getMarks() <= 55)
.map(p -> p).collect(Collectors.toSet());
System.out.println("After filtering Set Size: " + studentSetAfterFilter.size());
for(Student student:studentSetAfterFilter){
System.out.println("Set Objects: "+student.toString());
}
Set<Student> studentTreeSetAfterFilter=new TreeSet<>(Student.nameComparator);
studentTreeSetAfterFilter.add(s1);
studentTreeSetAfterFilter.add(s2);
studentTreeSetAfterFilter.add(s3);
studentTreeSetAfterFilter.add(s4);
studentTreeSetAfterFilter.add(s5);
studentTreeSetAfterFilter.add(s6);
studentTreeSetAfterFilter.add(s7);
studentTreeSetAfterFilter.add(s8);
studentTreeSetAfterFilter.add(s9);
studentTreeSetAfterFilter.add(s10);
studentTreeSetAfterFilter.add(s1);
studentTreeSetAfterFilter.add(s2);
studentTreeSetAfterFilter.add(s3);
studentTreeSetAfterFilter.add(s4);
for(Student student:studentTreeSetAfterFilter){
System.out.println("TreeSet Objects: "+student.toString());
}
}
}
I am trying to use SqlPredicate using hazelcast.
Code snippet:
private void testHazelCast() {
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
Employee e1 = new Employee("A", 20, 30);
Employee e2 = new Employee("C", 25, 45);
Employee e3 = new Employee("B", 30, 35);
Employee e4 = new Employee("F", 35, 30);
Employee e5 = new Employee("E", 40, 40);
Employee e6 = new Employee(null, 40, 20);
IMap<Employee, String> map = hazelcast.getMap("employee");
map.put(e1, "e1");
map.put(e2, "e2");
map.put(e3, "e3");
map.put(e4, "e4");
map.put(e5, "e5");
map.put(e6, "e6");
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate predicate = new SqlPredicate(String.format("name = A"));
Set<Employee> employeeSet = map.keySet(predicate);
System.out.println(employeeSet);
}
class Employee implements Serializable{
String name;
int age;
int weight;
public Employee(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
if (age != employee.age) return false;
if (weight != employee.weight) return false;
if (!name.equals(employee.name)) return false;
return true;
}
#Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age;
result = 31 * result + weight;
return result;
}
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;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
When I run this, I am getting the following execption:
Caused by: java.lang.IllegalArgumentException: There is no suitable accessor for 'name' on class 'class java.lang.String'
at com.hazelcast.query.impl.ReflectionHelper.createGetter(ReflectionHelper.java:150)
... 14 more
I need to filter the keys using the SqlPredicate and then retrieve the values using the keys. I have achieved this using PredicateBuilder.
Predicate predicate = e.key().get("name").equal("A");
I was trying to perform the same activity using the SqlPredicate.
Can anybody please point out where exactly I am doing wrong with SqlPredicate ?
Thanks,
Rahul
You are supposed to apply the predicate on values of the map, so try to use the IMap with String keys and Employee values
In an interview i came across this question.
Write a class which accepts a field of a bean class and sorts a list containing bean objects according to the field passed.
1) What should be the technique used for sorting?
I answered Comparator.
2) I don't want many Comparator classes created for each field. Can you write a generic Comparator which works for all fields.
Below is my code.
Please let me know if this is a correct way of doing or is there better way to do this. I request you to correct me if i am wrong.
public class GenericComparatorDemo {
static List<Employee> al = new ArrayList<Employee>();
static{
al.add(new Employee(45, "Vijay", "Bangalore", "Banking", 88, 99999));
al.add(new Employee(13, "Manoz", "Chennai", "Insurance", 48, 28000));
al.add(new Employee(79, "Ajay", "Hyderabad", "Real Estate", 54, 24000));
al.add(new Employee(21, "Sindu", "Noida", "Analyst", 89, 99998));
al.add(new Employee(67, "Honey", "Mumbai", "Social", 88, 111111));
al.add(new Employee(12, "Lucky", "Mysore", "Social", 86, 99997));
}
/**
* #param args
*/
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
System.out.println("Please enter the field on which you want to sort employee's...");
final String input = scn.nextLine();
if(null != input && !"".equals(input)){
Collections.sort(al, new Comparator<Employee>() {
#Override
public int compare(Employee o1, Employee o2) {
if("id".equals(input)){
return (o1.getId() < o2.getId()) ? -1 : ((o1.getId() == o2.getId()) ? 0 : 1);
}else if("name".equals(input)){
return o1.getName().compareTo(o2.getName());
}else if("location".equals(input)){
return o1.getLocation().compareTo(o2.getLocation());
}else if("department".equals(input)){
return o1.getDepartment().compareTo(o2.getDepartment());
}else if("rewardPoints".equals(input)){
return (o1.getRewardPoints() < o2.getRewardPoints()) ? -1 : ((o1.getRewardPoints() == o2.getRewardPoints()) ? 0 : 1);
}else if("salary".equals(input)){
return (o1.getSalary() < o2.getSalary()) ? -1 : ((o1.getSalary() == o2.getSalary()) ? 0 : 1);
}else{
return 0;// when proper field is not entered sorting will not happen
}
}
});
}else{
System.out.println("Please enter valid employee field to sort employee's...");
}
for(Employee alObj:al){
System.out.println("\n" + alObj.toString());
}
}
}
/// Employee Class ///
public class Employee {
private long id;
private String name;
private String location;
private String department;
private int rewardPoints;
private double salary;
public Employee(long id, String name, String location, String department,
int rewardPoints, double salary) {
this.id = id;
this.name = name;
this.location = location;
this.department = department;
this.rewardPoints = rewardPoints;
this.salary = salary;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public int getRewardPoints() {
return rewardPoints;
}
public void setRewardPoints(int rewardPoints) {
this.rewardPoints = rewardPoints;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
#Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", location="
+ location + ", department=" + department + ", rewardPoints="
+ rewardPoints + ", salary=" + salary + "]";
}
}
//// According to comments from tieTYT and radai. I have made the following changes. Please correct me if any thing is wrong ////
public class GenericComparatorReflectionDemo {
static List<Employee> al = new ArrayList<Employee>();
static{
al.add(new Employee(45, "Vijay", "Bangalore", "Banking", 88, 99999));
al.add(new Employee(13, "Manoz", "Chennai", "Insurance", 48, 28000));
al.add(new Employee(79, "Ajay", "Hyderabad", "Real Estate", 54, 24000));
al.add(new Employee(21, "Sindu", "Noida", "Analyst", 89, 99998));
al.add(new Employee(67, "Honey", "Mumbai", "Social", 88, 111111));
al.add(new Employee(12, "Lucky", "Mysore", "Social", 86, 99997));
}
/**
* #param args
*/
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
System.out.println("Please enter the field on which you want to sort employee's...");
final String input = scn.nextLine();
if(null != input && !"".equals(input)){
Collections.sort(al, new Comparator<Employee>() {
#Override
public int compare(Employee o1, Employee o2) {
try {
Field employeeField = Employee.class.getDeclaredField(input);
employeeField.setAccessible(true);
Comparable employeeFieldValue1 = (Comparable)employeeField.get(o1);
Comparable employeeFieldValue2 = (Comparable)employeeField.get(o2);
return employeeFieldValue1.compareTo(employeeFieldValue2);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
// when proper field is not entered sorting or any exception occurs
return 0;
}
}
});
}else{
System.out.println("Please enter valid employee field to sort employee's...");
}
for(Employee alObj:al){
System.out.println("\n" + alObj.toString());
}
}
}
This may be subjective as I can't read the interviewer's mind. But if I were you, I'd use reflection to find the field. If the field is Comparable, then use that interface. Otherwise, you'll have to ask the interviewer how you want it to work on certain types of fields.
The problem with your code is it's very specific to the current class. If a new field gets added, it won't be able to sort on that unless you write and compile new code. It also only works on this class. Using reflection, you could have it work on almost any class.
Yes, you can write a general purpose comparator using reflection. Once you have the field name you can retrieve the field value using reflection. After you do that you can use the fact that all the basic value holding classes in java (things like Boolean, Integer, String, uuid, date etc) are comparable, cast the values you got using reflection to Comparable, and compare them
To do this neatly you should abstract the concept of getting the value to compare into an interface (or function in Java 8) as follows:
This function will create you a Comparator that uses the getter Function to read the value from the a bean:
public static <T> Comparator<T> createComparator(Function<T, R extends Comparable> getter)
{
return (obj1, obj2) -> getter.apply(obj1).compareTo(getter.apply(obj2);
}
That can be used like this:
Collections.sort(employees, createComparator((employee) -> employee.getName()));
If you're set on using String names to read the field then use just use a reflective implementation of the getter function like this:
private Function<Employee, Comparable> reflectiveGetter(String fieldName) throws NoSuchFieldException
{
Field field = Employee.class.getDeclaredField(fieldName);
field.setAccessible(true);
return (employee) ->
{
try
{
return (Comparable)field.get(employee);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
}
That can be used like this:
Collections.sort(employees, reflectiveGetter("name"));
The exact same thing can be acheived in any version of Java using interfaces only it's a bit more verbose.