【问题标题】:Sorting a List of Objects Based on 1 of its Fields根据其中一个字段对对象列表进行排序
【发布时间】:2012-08-02 10:55:27
【问题描述】:

你好 stackoverflow 社区! 我是这些论坛的新手,对 java 和 android 编程也很陌生——这恰好是我的问题的对象——对于任何错误,提前抱歉!

我的问题是排序。我正在寻找一种基于我选择的字段对对象进行排序的方法(不是基于第一个字段排序,然后是下一个字段,等等,例如比较器链接)。我相信我已经找到了解决问题的方法:

https://stackoverflow.com/a/5113108/1549672

但我实际上无法使其正常工作。由于缺乏 Java 经验,我怀疑我可能遗漏了一些东西,所以欢迎任何帮助!

这是我正在尝试的:

作为我的班级-

public class ItemLocation {
String title;
int id;
}

作为我的职责-

public void sort(final String field, List<ItemLocation> itemLocationList) {
    Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            if(field.equals("title")) {
                return o1.title.compareTo(o2.title);
            } else if(field.equals("id")) {
                return Integer.valueOf(o1.id).compareTo(o2.id);
            }
            return 0;
        }
    });
}

使用这些,有人可以举一个使用这种方法的例子吗?我试图填充一个 ArrayList 并对其进行排序,但无济于事。

感谢您的帮助!

【问题讨论】:

    标签: java sorting


    【解决方案1】:

    如果它们不相等,则不应从 Comparator.compare 方法返回 0。从 API 文档来看,这是合同“好的”,但并不完全鼓励:

    通常是这样,但并不严格要求 (compare(x, y)==0) == (x.equals(y))。一般来说,任何比较器 违反此条件应明确表明这一事实。这 推荐的语言是“注意:这个比较器强加的顺序是 与equals不一致。”


    在我看来,您应该为每个字段返回一个特定的Comparator:

    Comparator<ItemLocation> titleComparator = new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            return o1.title.compareTo(o2.title);
        }
    }
    
    Comparator<ItemLocation> idComparator = new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            return Integer.valueOf(o1.id).compareTo(o2.id);
        }
    }
    
    public void sort(final String field, List<ItemLocation> itemLocationList) {
    
        final Comparator<ItemLocation> comparator;
    
        if(field.equals("title")) {
            comparator = titleComparator;
        } else if (field.equals("id")) {
            comparator = idComparator;
        } else {
            throw new IllegalArgumentException("Comparator not found for " + field);
        }
    
        Collections.sort(itemLocationList, comparator);
    }
    

    【讨论】:

    • 谢谢您,先生!我包含 return 0 的原因是因为 eclipse 告诉我该方法必须返回一个整数,而我不确定还要放什么!这是一个更容易理解的来自 C++ 背景的实现!再次感谢您!
    【解决方案2】:

    您可以发布不起作用的调用代码吗?我看不出您提供的代码有什么明显错误。

    首先,您可以尝试像这样添加一个额外的 else 案例:

    else {
        throw new IllegalArgumentException("Unrecognised field name");
    }
    

    目前,如果您的调用代码中有错字,比较器将始终返回 0,这会使列表未排序。

    一种更可靠的传递字段的方法是声明一个枚举:

    enum ItemLocationField {
        TITLE,
        ID
    }
    

    那么你的条件会变成:

    if (field == ItemLocationField.TITLE)
    

    等等。这将减少打错字的机会(编译器会告诉你如果你这样做了)。

    【讨论】:

      【解决方案3】:

      除了 returning 0 并将参数与 equals 进行比较之外,我没有发现任何问题。你可以通过throwing RuntimeException而不是returning 0来改进它,并使用equalsIgnoreCase而不是equals方法,最好忽略参数的大小写。

      public static void sort(final String field, List<ItemLocation> itemLocationList) {
          Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
              @Override
              public int compare(ItemLocation o1, ItemLocation o2) {
                  if(field.equalsIgnoreCase("title")) {
                      return o1.title.compareTo(o2.title);
                  } else if(field.equalsIgnoreCase("id")) {
                      return Integer.valueOf(o1.id).compareTo(o2.id);
                  }else
                      throw new IllegalArgumentException("Invalid Parameter .");
              }
          });
      }
      

      【讨论】:

      • 我认为这主要是由于我缺乏 java 经验...Eclipse 刚刚告诉我实现必须返回一个整数!
      【解决方案4】:

      1.如果您想仅基于一个属性对对象进行排序,请选择java.lang.Comparable 接口以及Collections.sort(List&lt;T&gt; list)

      2.如果您想根据多个属性对对象进行排序,请选择 java.util.Comparator 接口连同Collections.sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c)

      【讨论】:

      • 谢谢!我主要是在寻找一种基于包含多个属性的对象的一个​​属性进行排序的方法!
      • 是的……这就是我的第一点建议……基于一个属性进行排序。第二点是增加额外知识
      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2012-09-14
      • 1970-01-01
      • 2017-04-06
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多