Home > Enterprise >  How to selection sort a list of array objects by the value of an array objects
How to selection sort a list of array objects by the value of an array objects

Time:11-07

I have a Students list that I would want to sort using Selection Sort algorithm. I want to sort Students list based on first name, age and id. My student class is a POJO class just with getters and setters. It has 4 instance variables- firstName, lastName, age and id.

My code below-

private static void selectionSort(Student[] list, String key) {
        for(int i = 0; i< list.length - 1; i  ){
            int min_index = i;
            for(int j = i 1; j < list.length; j  ) {
                // TO-DO for each of the unsorted elements
                // if element < currentMinimum
                if(list[j].compareTo(list[min_index])){
                  // TO-DO
                }
            }
        }
    }

Here, list parameter is the list of Student objects. I am passing key parameter here which would be either first name or id or age.

I have written my swap method as below-

private static void swap(Students[] list, int index1, int index2) {
  Student temp = list[index1];
  list[index1] = list[index2];
  list[index2] = temp;
}

I am calling my method like this-

selectionSort(list, "firstName");

selectionSort(list, "id");

selectionSort(list, "age");

I am not sure how to compare the value in nested loop for each of the unsorted elements. I tried using compareTo but it gives me error.

CodePudding user response:

The compareTo method does not return a boolean, it returns an int. It returns either 1, 0 or -1. Being 1 if greater, -1 if less and 0 if equal.

you can achieve what you want by doing foo.compareTo(boo) < 0;

CodePudding user response:

I suggest two different approaches to this question. If you are doing a homework assignement or similar and you don't want to complicate things, you may choose the first approach. It is not recommended to hardcode the field names of your class, but since you are looking for a way to get field values by names:

SOLUTION1: "NOT RECOMMENDED FOR PRODUCTION CODE"

The comparator:

    public static Integer compareTwoStudents(Student student1, Student student2, String field) throws NoSuchFieldException {
        switch (field) {
            case "id":
                return student1.getId().compareTo(student2.getId());
            case "name":
                return student1.getName().compareTo(student2.getName());
            case "age":
                return student1.getAge().compareTo(student2.getAge());
            default:
                throw new NoSuchFieldException();
        }
    }

The sorting algorithm:

        public static void selectionSort(Student[] list, String key) {
        for (int i = 0; i < list.length - 1; i  ) {
            int minElementIndex = i;
            for (int j = i   1; j < list.length; j  ) {
                if (compareTwoStudents(list[minElementIndex], list[j], key) > 0) {
                    minElementIndex = j;
                }
            }
            if (minElementIndex != i) {
                Student temp = list[i];
                list[i] = list[minElementIndex];
                list[minElementIndex] = temp;
            }
        }
    }

"SOLUTION 2" Using generics, you can define a generic getter method and a generic comparator as below:

Generic getter:

    private static <T> Field getField(Class<T> clazz, String fieldName) {
        try {
            return clazz.getDeclaredField(fieldName);
        } catch (java.lang.NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

Generic comparator:

    public static <T> Comparator<T> getGenericComparatorLambda(Class<T> clazz,
                                                               String fieldName) {
        final Field field = getField(clazz, fieldName);
        field.setAccessible(true);
        Comparator<T> orderByComparator = (f1, f2) -> {
            Comparable compA, compB;
            try {
                compA = (Comparable) field.get(f1);
                compB = (Comparable) field.get(f2);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
            return Objects.compare(compA, compB, Comparator.naturalOrder());
        };
        return orderByComparator;
    }

The sorting algorithm:

    public static void selectionSort(Student[] list, String key) {
        for (int i = 0; i < list.length - 1; i  ) {
            int minElementIndex = i;
            for (int j = i   1; j < list.length; j  ) {
                if (getGenericComparatorLambda(Student.class, key).compare(list[minElementIndex], list[j]) > 0) {
                    minElementIndex = j;
                }
            }
            if (minElementIndex != i) {
                Student temp = list[i];
                list[i] = list[minElementIndex];
                list[minElementIndex] = temp;
            }
        }
    }
  • Related