【问题标题】:Can a Java Method sort an Array based on an argument with an object variable reference?Java 方法可以根据带有对象变量引用的参数对数组进行排序吗?
【发布时间】:2018-04-15 12:45:17
【问题描述】:

我对 Java 很陌生,我正在尝试创建一个方法(用于类项目),该方法根据作为参数提供的对象变量引用对数组进行排序。因此,如果提供了 Object 变量 refrence 'name',它将用 'name' 替换 'sort_variable',但如果提供了 'last_name',它会将 'sort_variable' 替换为 '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;

我主要有:

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

我好像买不到

    array[index].sort_variable

有效地成为

    array[index].name

我应该注意,我得到的错误是: 错误:找不到符号

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

我想我想知道这是一件简单的事情,我只是弄错了,还是可能超出了初学者阶段?如果它简单的指针会很棒。我所搜索的任何内容都没有让我了解我所缺少的东西。 提前谢谢。

【问题讨论】:

    标签: java arrays sorting methods


    【解决方案1】:

    您需要使用反射来做到这一点,这在 99% 的情况下是个坏主意。 Java 不通过字符串名称访问属性和方法。但它有 lambda 表达式和方法引用。您的方法应该接受一个将名册转换为姓氏的函数,而不是使用字符串。然后代码将简化为

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

    例如:

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

    或者,如果 lastName 是一个公共字段(这将是一个糟糕的设计)

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

    【讨论】:

    • 谢谢,JB。刚刚学习数组列表,所以我会试一试。
    • 在静态初始化程序中填充 Map&lt;String,Comparator&lt;Roster&gt;&gt; 而不是反射呢?
    • @erickson 当然,这是可能的。但我的猜测是,OP 希望调用者能够传递任何“属性名称”,即任何比较标准,而不仅仅是映射的一组预定义键。你提出的解决方案基本等同于 Jochen 的解决方案,但是 enum 更安全、更干净。
    • 是的,我想听起来确实如此。
    【解决方案2】:

    您可以将sort_variable 映射到enum(或使用switch 语句)并使用与enum 关联的Comparable 进行排序。

    这里是这个想法的大纲:

    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;
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用commons-beanutils API 动态获取属性值。以下是根据给定属性排序的代码 sn-p。请记住,您需要处理 try 块中的 null 值。

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-16
        • 2012-05-19
        • 2021-09-23
        • 2021-06-05
        • 1970-01-01
        • 1970-01-01
        • 2013-11-25
        相关资源
        最近更新 更多