Reputation: 227
Hi I have a list of object which contains four object (Employee,Student,Patient,Customer). I need to sort these list in ascending order based on their corresponding ID.
When I am using Collections.sort(list)
method is giving ClassCastException.
Below is complete code which I am using...
Note: I tried with Comparator
interface also, but couldn't able to define the logic inside compare()
method to sort these object. If list contain two object then it is easy to define logic to sort these object inside, but if list contains more than tow object then it is very difficult to define sorting logic inside compare()
method.
Can any one help me how to short this list? Please modify the below code and provide me the solution. The output should be in sorted order like [10,20,30,40,50,60,70,90]
public class Test
{
public static void main(String[] args)
{
List list = new ArrayList();
list.add(new Employee(50));
list.add(new Customer(10));
list.add(new Patient(60));
list.add(new Student(90));
list.add(new Employee(20));
list.add(new Customer(40));
list.add(new Patient(70));
list.add(new Student(30));
Collections.sort(list);
System.out.println(list);
}
}
class Patient implements Comparable<Patient>
{
int pId;
Patient(int pId)
{
this.pId = pId;
}
@Override
public int compareTo(Patient o)
{
return this.pId - o.pId;
}
@Override
public String toString()
{
return this.pId + "";
}
}
class Employee implements Comparable<Employee>
{
int empId;
Employee(int empId)
{
this.empId = empId;
}
@Override
public int compareTo(Employee o)
{
return this.empId - o.empId;
}
@Override
public String toString()
{
return this.empId + "";
}
}
class Customer implements Comparable<Customer>
{
int cId;
Customer(int cId)
{
this.cId = cId;
}
@Override
public int compareTo(Customer o)
{
return this.cId - o.cId;
}
@Override
public String toString()
{
return this.cId + "";
}
}
class Student implements Comparable<Student>
{
int sId;
Student(int sId)
{
this.sId = sId;
}
@Override
public int compareTo(Student o)
{
return this.sId - o.sId;
}
@Override
public String toString()
{
return this.sId + "";
}
}
Upvotes: 1
Views: 395
Reputation: 91
You can do it easily just by adding a common interface for all your POJOs, define a method to get the id and then write a custom comparator for comparing.
Heres the rewritten version which sorts the Object.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
class Test {
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Employee(50));
list.add(new Customer(10));
list.add(new Patient(60));
list.add(new Student(90));
list.add(new Employee(20));
list.add(new Customer(40));
list.add(new Patient(70));
list.add(new Student(30));
Collections.sort(list, new IDComparator());
Stream.of(list).forEach(System.out::println);
}
}
class Patient implements CommonObject {
int pId;
Patient(int pId) {
this.pId = pId;
}
@Override
public int getId() {
return this.pId;
}
}
class Employee implements CommonObject {
int empId;
Employee(int empId) {
this.empId = empId;
}
@Override
public int getId() {
return this.empId;
}
}
class Customer implements CommonObject {
int cId;
Customer(int cId) {
this.cId = cId;
}
@Override
public int getId() {
return this.cId;
}
}
class Student implements CommonObject {
int sId;
Student(int sId) {
this.sId = sId;
}
@Override
public int getId() {
return this.sId;
}
}
Now Custom Comparator:
import java.util.Comparator;
public class IDComparator implements Comparator<CommonObject> {
@Override
public int compare(CommonObject o1, CommonObject o2) {
if (o1.getId() == o2.getId())
return 0;
else if (o1.getId() > o2.getId())
return 1;
else
return -1;
}
}
Common Object Interface:
public interface CommonObject {
int getId();
}
Tested, Heres the output of above code:
[Customer@23223dd8, Employee@4ec6a292, Student@1b40d5f0, Customer@ea4a92b, Employee@3c5a99da, Patient@47f37ef1, Patient@5a01ccaa, Student@71c7db30]
Thanks, any suggestions are most welcome.
Upvotes: 0
Reputation:
Define a superclass, for example Person
, and add your id
there. The compare based on id logic should be implemented there as well.
public class Person implements Comparable<Person> {
private int id;
// getters, setters, compareTo, etc
}
Make all your base classes extend from Person
public class Student extends Person { ... }
public class Customer extends Person { ... }
public class Employee extends Person { ... }
public class Patient extends Person { ... }
Define you List
in terms on Person
and apply sort on that.
public static void main(String[] args)
{
List<Person> list = new ArrayList<>();
list.add(new Employee(50));
list.add(new Customer(10));
list.add(new Patient(60));
list.add(new Student(90));
list.add(new Employee(20));
list.add(new Customer(40));
list.add(new Patient(70));
list.add(new Student(30));
Collections.sort(list);
System.out.println(list);
}
Upvotes: 1
Reputation: 691635
Define an interface Identifiable
(or a superclass Person), with a method int getId()
.
Make all your classes implement that interface (or extend that superclass).
Stop using raw types, and thus use a List<Identifiable>
instead of a List
.
Then sort the list using a Comparator<Identifiable>
, which can be defined using Comparator.comparingInt(Identifiable::getId)
.
All your classes should not implement Comparable. Their ID does not define their natural ordering. You just happen to sort them by ID in this specific use-case. And should thus use a specific comparator.
Upvotes: 3
Reputation: 2525
Create class like person which has id attribute. Then extend all theses classes by it. Then You only need to write compare for person class
Upvotes: 0