简体   繁体   中英

Can a Java Method sort an Array based on an argument with an object variable reference?

I am pretty new to Java and am trying to make a Method (for a class project) that sorts an array based on an object variable reference that is provided as the argument. So that if the Object variable refrence 'name' is provided it would replace the 'sort_variable' with 'name', but if 'last_name' is provided it would replace the 'sort_variable' with 'last_name'.

Roster[] sort (Roster [] array, String sort_variable){
    Roster temp_player = new Roster();
    for(int sort_iters = 0; sort_iters < array.length; sort_iters++) {
            for(int index = 0; index < array.length-sort_iters - 1 ; index++) {
                if (array[index].sort_variable.compareTo(array[index+1].sort_variable) < 0){
                    temp_player = array[index];
                    array[index] = array[index+1];
                    array[index+1] = temp_player;

In main I have:

    String sort_variable = "name";
    array = sort(array, sort_variable);

I don't seem to be able to get

    array[index].sort_variable

to effectively become

    array[index].name

I should note, the error I am getting is: error: cannot find symbol

    if(array[index].sort_variable.compareTo(array[index+1].sort_variable) < 0){
                   ^

I guess I am wondering is this a simple thing I am just getting wrong, or is it something that is probably beyond the beginner stage? If its simple a pointer would be great. Nothing I've searched for has clued me in on what I am missing. Thanks, in advance.

You would need to use reflection to do that, which is, in 99% of the cases, a bad idea. Java doesn't access attributes and methods by String names. But it has lambda expressions and method references. Instead of using a String, your method should accept a function which transforms a Roster into a last name. And the code would then be reduced to

Arrays.asList(array).sort(Comparator.comparing(function));

For example:

Arrays.asList(array).sort(Comparator.comparing(Roster::getLastName));

or, if lastName is a public field (which would be bad design)

Arrays.asList(array).sort(Comparator.comparing(roster -> roster.lastName));

You could map the sort_variable to an enum (or use a switch statement) and use a Comparable associated with the enum to sort.

Here's the outline of the idea:

class Roster {
    String lastName, firstName;

    String getFirstName() {
        return firstName;
    }

    String getLastName() {
        return lastName;
    }
}
enum SortOrder {
    firstName(Comparator.comparing(Roster::getFirstName)),
    lastName(Comparator.comparing(Roster::getLastName));

    final Comparator<Roster> comparator;
    SortOrder(Comparator<Roster> comparator) {
        this.comparator = comparator;
    }
}

Roster[] sort(Roster [] array, String sort_variable) {
    SortOrder sortOrder = SortOrder.valueOf(sort_variable);
    Arrays.sort(array, sortOrder.comparator);
    return array;
}

You could use commons-beanutils API to get the property values dynamically. Following is a code snippet that sorts based on the given property. Keep in mind that you need to handle null values in the try block.

final String propertyUsedForSorting = "firstName";
Arrays.sort(persons, new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        try {
            Comparable prop1 = (Comparable) PropertyUtils.getProperty(o1, propertyUsedForSorting);
            Comparable prop2 = (Comparable) PropertyUtils.getProperty(o2, propertyUsedForSorting);
            return prop1.compareTo(prop2);
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException("Could not resolve the property: " + propertyUsedForSorting, e);
        } catch (ClassCastException e) {
            throw new RuntimeException("Cannot use property " + propertyUsedForSorting + " for sorting.");
        }
    }
});

https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils

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