【问题标题】:Is there an easy way to sort an arraylist in this manner?有没有一种简单的方法可以以这种方式对数组列表进行排序?
【发布时间】:2013-03-08 16:21:56
【问题描述】:

我想知道是否有一种方法可以对自定义对象的 Arraylist 进行排序以适应下面解释的情况?我假设我必须编写一个自定义比较器。

假设我有一个如下所示的对象类:

public class Person {
    private String status;    //options: Online, Away, Offline
    private String name;      //Person's name
    private Date date;        //Last signed on

    //basic constructor
    public Person() {
        //set default values
    }

    //constructor to set all variables
    public Person(String s, String n, Date d) {
        status = s;
        name = n;
        date = d;
    }

    //setters & getters for each of the fields
}

根据姓名和日期进行排序应该相当容易。但是,我想知道如何根据状态进行排序?我希望能够根据此人当前是否在线以及谁离线对我的数组进行排序。我不太关心谁不在。

上面的类只是一个示例类。我的实际班级有一个 JLabel 根据状态设置一个图标。 setText() 仍未使用。我想到了将标签设置为 0、1 和 2 值并仅使用典型整数比较器的可能性,但我不确定这是否是一种建议的方式。

当然我在这里缺少一个明显的解决方案,所以也许评论或链接可以提供必要的信息。我知道这里有大量的“排序数组列表”线程,我浏览了很多。他们中的大多数只是按字母顺序或整数排序字符串。

【问题讨论】:

  • Status 应该是一个枚举。
  • 请参阅 javadoc 以了解在编写比较器后如何排序的集合:docs.oracle.com/javase/1.5.0/docs/api/java/util/…
  • @mrhobo 我会读入 Enum。使用枚举,我假设我会给它们值并根据整数值进行排序? Nattyddubbs,我正在阅读链接。
  • 这个问题没有意义的是没有“自然”的状态排序,除非你使用String ordering where Online > Offline > Away。使用Enum,您可以在对象中定义它们的顺序,或者只是将它们放在枚举声明中所需的“顺序”中。
  • @nattyddubbs 哇,我不知道在枚举中将它们按所需顺序自动定义为这样。我显然需要阅读枚举。谢谢你。我为我的无知道歉。

标签: java sorting collections arraylist


【解决方案1】:

如果我理解正确,您基本上想对 2 个字段进行排序 - 主要字段是状态(因此具有相同状态的人会聚集在一起),然后是每个具有相同状态的人的名称。

执行此操作的比较器如下所示:

 public class CompositePersonComparator implements Comparator<Person> {    
    @Override
    public int compare(Person a, Person b) {
       //1st and foremost - see if they are not of the same status.
       int statusComparison = a.getStatus().compareTo(b.getStatus());
       if (statusComparison!=0) return statusComparison;
       //logical else - same status, sort by name
       return a.getName().compareTo(b.getName());
    }
 }

【讨论】:

  • 您确实理解我的要求正确。谢谢你的例子,如果你不介意你能解释一下它是如何排序的吗?我如何知道它是按在线、离线还是离开排序?
  • @WilliamShatner - 它依赖于所涉及的所有属性都与自身可比。整数、字符串和大多数内置函数都是。如果您按照上面的建议将 status 设置为 Enum ,则您可以使其实现 Comparable 依赖于内置的枚举比较(按它们的写入顺序)。字符串按字母顺序比较。 compare() 方法的返回值 0 表示相等 - 将 a.compareTo(b) 视为数学中的“类似” a-b
  • 感谢您的解释。我相信上面的例子只会按字母顺序对字符串进行排序。所以我确实需要使用枚举(如 Thorn 所示)。
【解决方案2】:

在这里使用枚举很有用 enum MyEnum { ONLINE, AWAY, OFFLINE;}

【讨论】:

  • 这实际上可以很好地回答这个问题。但是,您可能想稍微扩展一下它的工作原理。
  • 确实,这是对这个问题的一个很好的回答。不过,我同意 Andrew 的观点,我对 Enums 了解不多,所以如果你像 Thorn 那样扩展它会很棒。 +1 虽然你是对的。
【解决方案3】:

我建议我们将状态作为枚举数据类型而不是字符串来处理,因为它只能是少数字符串之一。这使得编写可读的 compareTo 方法变得容易:

public class Person implements Comparable<Person> {
  private Status currentStatus;   
  private String name;      //Person's name
  private Date date;        //Last signed on

  enum Status {ONLINE, AWAY, OFFLINE};

  //basic constructor
  public Person()  {
     //set default values
  }

  //constructor to set all variables
  public Person(Status s, String n, Date d) {
     currentStatus = s;
     name = n;
     date = d;
  }

 /**
  *   Order the Persons first by status where all ONLINE Persons are listed first.
  */
  @Override
  public int compareTo(Person other) {
     if(other.currentStatus == currentStatus)
        return name.compareTo(other.name);

     return currentStatus.ordinal() - other.currentStatus.ordinal();
  }
}   

【讨论】:

  • 感谢您提供的优雅示例。你是绝对正确的。我现在需要改变我的类和使用这个变量的类的结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 2010-09-23
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多