【问题标题】:How to sort an arraylist of objects?如何对对象的arraylist进行排序?
【发布时间】:2014-04-13 06:08:52
【问题描述】:

我有课

public class SMS 
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;
}

现在我已经创建了一个对象数组列表

ArrayList<SMS> temp = new ArrayList<SMS>();

我已经添加了值。现在我想根据时间戳对 arrayList 进行排序。

如何根据时间戳对 arrayList 进行升序/降序排序?

【问题讨论】:

  • timestamp的格式是什么?
  • 它是一个字符串,例如 timestamp="1033123131";
  • 您将其存储为字符串是否有原因? long 类型不是更好吗?
  • 我会将它转换为 long 这不是问题。问题是我该如何排序呢?

标签: java sorting arraylist


【解决方案1】:
Collections.sort(temp);

将对Comparable对象的集合进行排序,因此SMS类必须实现Comparable&lt;SMS&gt;

public class SMS implementes Comparable<SMS>
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;

    @Override
    public int compareTo(SMS other) {
       //for instance
       return addr.compareTo( other.addr );
    }
}

在实现Comparable 时同时实现equals()hashcode() 通常是一个好习惯,以便对象之间的相等性与它们的比较一致。此外,您应该添加一些针对空值的保护:

public class SMS implements Comparable<SMS>
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;

    @Override
    public int compareTo(SMS other) {
       //for instance
       if( addr == null ) {
           return Integer.MAX_VALUE;
       }
       return addr.compareTo( other.addr );
    }

    @Override
    public boolean equals(Object other) {
       //for instance
       if( other instanceof SMS ) {
          if( addr == null && ((SMS) other) != null ) {
              return false;
          }
          return addr.equals(((SMS) other).addr);
       } else {
          return false;
       }
       return addr.compareTo( other.addr );
    }

    @Override
    public int hashcode() {
       //for instance
       if( addr == null ) {
           return 0;
       }
       return addr.hashcode();
    }
}

【讨论】:

【解决方案2】:

要比较包含时间戳的字符串,您需要先将它们解析为长 Long.parseLong(timestamp),然后使用 Long.compare(x,y) 比较数值。

所以不妨试试Collections.sort(yorList, yourOwnComparator) 之类的

Collections.sort(temp, new Comparator<SMS>() {
    @Override
    public int compare(SMS o1, SMS o2) {
        return Long.compare(Long.parseLong(o1.timestamp), 
                            Long.parseLong(o2.timestamp));
    }
});

如果您可以将时间戳类型更改为long,则此代码可能如下所示

Collections.sort(temp, new Comparator<SMS>() {
    @Override
    public int compare(SMS o1, SMS o2) {
        return Long.compare(o1.timestamp, o2.timestamp);
    }
});

在 Java8 中,您甚至可以使用 lambda 来进一步缩短代码

Collections.sort(temp, (SMS o1, SMS o2) -> Long.compare(o1.timestamp, o2.timestamp));

甚至

Collections.sort(temp, (o1,  o2) -> Long.compare(o1.timestamp, o2.timestamp));

【讨论】:

  • 这是一个不错的选择,可以防止 o1 和/或 o2 为空。
  • @Snicolas 真的。为了避免 NPE OP 必须确保 timestamp 不是 null。但我认为让timestamp 成为null 可能是更大的问题,所以在这种情况下抛出 NPE 将通知代码中的某个地方(早期)存在一种方式/错误,它让时间戳为nulls。决定在哪里处理它属于 OP。
【解决方案3】:

使用Comparable(见example here), 它应该是这样的:

public class SMS implements Comparable<SMS>{

    ....

    public int compareTo(SMS compareSms) { 
        return this.timestamp.compareTo(compareSms.timestamp);
    }
}

【讨论】:

    【解决方案4】:

    这是一般测试代码:

    ArrayList<SMS> temp = new ArrayList<SMS>();
    
    // testing values
    SMS a = new SMS();
    a.setTime("a time");
    SMS b = new SMS();
    b.setTime("b time");
    SMS c = new SMS();
    c.setTime("c time");
    temp.add(a);
    temp.add(b);
    temp.add(c);
    
    // descending sort
    Collections.sort(temp, new Comparator<SMS>() {
        public int compare(SMS text1, SMS text2) {
            // compare timestamps from the SMSs
            return text2.getTime().compareTo(text1.getTime());
        }
    });
    
    // print it out to test
    for (SMS sms : temp) {
        System.out.println(sms.getTime());
    }
    

    如果我想将它从升序更改为降序,我只需要切换比较文本消息的方式。看看这个:

    return text2.getTime().compareTo(text1.getTime()); // descending
    return text1.getTime().compareTo(text2.getTime()); // ascending
    

    注意:我假设 getTime() 返回文本消息的时间戳,您需要将此导入语句添加到您的类中:import java.util.Collections; 或只是 import java.util.*;

    要使用getTime()setTime(String timestamp) 方法,您的类可能如下所示:

    public class SMS 
    {
        public String addr;
        public String body;
        public String type;
        public String timestamp;
    
        public void setTime(String timestamp) {
            this.timestamp = timestamp;
        }
    
        public String getTime() {
            return timestamp;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-06
      • 2015-12-27
      • 1970-01-01
      • 2019-11-24
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      相关资源
      最近更新 更多