简体   繁体   中英

How to sort objects in arrayList by their class?

I have an ArrayList that holds 2 types of objects in it (objects from class Student and objects from class Teacher ).

My question is how can I sort it so that all objects that are from Student to appear first and then all objects that are from class Teacher to appear after them.

For example: Student1, Student2, Student3, Teacher1,Teacher2,Teacher3

Here is my code:

public ArrayList sortList(){

    ArrayList<Student> students = new  ArrayList<Student>();
    ArrayList<Teacher> teachers = new  ArrayList<Teacher>();
    ArrayList<Person> university = new  ArrayList<Person>();
    for(Person p : list){
        if(p.getClass().getSimpleName().equals("Teacher")){
            teachers.add((Teacher)p);
        };
        if(p.getClass().getSimpleName().equals("Student")){
            students.add((Student)p);
        }
        university.addAll(students);
        university.addAll(teachers);
    }
    return university;
}

You can use Collections.sort(list,comparator)

In the Comparator you can compare the class names because (luckily) S is before T in the alphabet:

   List<Object> studentsAndTeachers = // ...
   Collections.sort(studentsAndTeachers, (o1, o2) -> o1.getClass().getName().compareTo(o2.getClass().getName()));

of cause you ave to apply other sorting criteria first or extend the comparator to recognize them...

Now it should work like a bread with butter:

public class Main
{
    public static void main(String[] args)
    {
        List<Human> humans = new ArrayList<>();
        humans.add(new Teacher("Teacher1"));
        humans.add(new Teacher("Teacher2"));
        humans.add(new Student("Student3"));
        humans.add(new Student("Student1"));
        humans.add(new Teacher("Teacher3"));
        humans.add(new Student("Student2"));

        Collections.sort(humans, new Comparator<Human>()
        {
            @Override
            public int compare(Human o1, Human o2)
            {
                if (o2 instanceof Teacher) {
                    return -1;
                } else if (o1 instanceof Teacher && o2 instanceof Student) {
                    return 1;
                }
                /* other checks not about being teacher or student goes here... */                
            }
        });
        System.out.println(humans);
    }
}

interface Human
{
    String getName();

    void setName(String name);
}

class Teacher implements Human
{
    private String name;

    public Teacher(String name)
    {
        super();
        this.name = name;
    }

    @Override
    public String getName()
    {
        return name;
    }

    @Override
    public void setName(String name)
    {
        this.name = name;
    }
}

class Student implements Human
{
    private String name;

    public Student(String name)
    {
        super();
        this.name = name;
    }

    @Override
    public String getName()
    {
        return name;
    }

    @Override
    public void setName(String name)
    {
        this.name = name;
    }
}

Sorting like this will do the job for you, although is not a quite good solution generally speaking.

Collections.sort(classroom, (o1, o2) -> {
    if (o1 instanceof Student && o2 instanceof Teacher) {
        return -1;
    }

    if (o1 instanceof Teacher && o2 instanceof Student) {
        return 1;
    }

    return 0;
});

Here's a Comparator class that orders Human objects based on class name, and then the value of the name attribute.

    public class Comparator<Human> {
        public int compare(Human h1, Human h2) {
            int res = h1.getClass().getName().compareTo(
                         h2.getClass().getName());
            if (res == 0) {
                res = h1.getName().compareTo(h2.getName());
            }
            return res;
        }
    }

If you use this with Collections.sort(...) , you can sort the list into the required order.

Note that this implementation:

  • sorts objects with the same type based on their name (as implied by the example), and
  • doesn't break if you add more subclasses of Human .

You can use Comparator.comparing for that:

list.sort(Comparator.comparing(Teacher.class::isInstance))

This works because Class.isInstance returns boolean which is wrapped into Boolean which implements Comparable .

您可以将Comparator.comparinglistName.sort()一起使用,如下所示;

list.sort(Comparator.comparing(o -> o.getClass().getName()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM