java - Android - java - 如何通过 GregorianCalendar 参数对对象列表进行排序

标签 java android sorting collections calendar

我想显示按日期参数以新月顺序排序的对象列表。 我尝试了很多方法。但这不起作用。它不会更改列表中对象的顺序。 我访问此寻求帮助: Android: How to sort list items according to dates

How to Sort Date in descending order From Arraylist Date in android?

https://www.quora.com/How-do-I-sort-an-ArrayList-of-objects-by-each-objects-integer-parameter

这是我的代码:

我的类对象

public class Evento extends GregorianCalendar {

public Calendar date;
public String tipo = " ";
public String a = " ";
public String b = " ";
public String c = " ";

还有我的主要 Activity :

public void implementList (View view){

    List <Evento> listEventosAll = new ArrayList<>();

    listEventosAll.addAll(listEventos1);

    listEventosAll.addAll(listEventos2);

    Collections.sort(listEventosAll,  new Comparator<Evento> (){
         public int compare(Evento evento1, Evento evento2) {
             if (evento1.date.getTime() == null || evento2.date.getTime() == null)
                 return 0;
             return evento1.date.getTime().compareTo(evento2.date.getTime());
        }

   }); 


    EventoAdapter adapter = new EventoAdapter(this,listEventosAll);
    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setAdapter(adapter);
}

正在填充 ListEventos1

public static Evento setEvento(Calendar day, String a, String b) {

Evento evento = new Evento();
evento.date = day;
evento.a = a;
evento.b = b; 
return evento;

}

//创建列表:

公共(public)静态ArrayList listEventos1(int年份){

Calendar day = calculateCertainTuesday(year);

ArrayList <Evento> list = new ArrayList<Evento>();

list.add(setEvento(day, "Certain Tuesday”, "do this"));

day.add(Calendar.DAY_OF_MONTH, 1); 

list.add(setEvento(day, "Certain Wendsday”, "do that"));

day.add(Calendar.DAY_OF_MONTH,-2); 

list.add(setEvento(day, "Certain Monday", "do what"));


day.add(Calendar.DAY_OF_MONTH, -1); 

list.add(setEvento(day, "SUNDAY", "don’t do"));


return list;

}

最佳答案

编辑我彻底修改了我的答案,以回应对您问题的新编辑。

问题是,对于填充 listEventos1 的每个 Evento,您使用相同的 Calendar (变量名称 day )。你正在这样做:

list.add(setEvento(day, "Certain Tuesday”, "do this"));

然后是这个:

day.add(Calendar.DAY_OF_MONTH, 1); 
list.add(setEvento(day, "Certain Wendsday”, "do that"));

但是调用 Calendar#add 会发生什么?确实是这样

Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules.

换句话说,Calendar 是一个可变类,即它可以更改状态,这与 String 不同,不可变并且永远都是一样的。别担心,你不是第一个犯这个错误的人,那就是 partly why Java introduced a new Date API (更准确地说,这是因为这使得类不是线程安全的)。

换句话说,每当您调用 Calendar#add 方法时,listEventos1 中的所有对象都会发生变化,因为它们都包含Calendar 的同一实例。有关为什么会发生这种情况的一个很好的例子,请参阅 this answer .

验证这一点的一种方法是使用 == 运算符在 Comparator 中添加补充检查。如果两个变量指向相同实例,==将返回true:

Collections.sort(listEventosAll,  new Comparator<Evento> (){
    public int compare(Evento evento1, Evento evento2) {
        if(evento1.date.getTime() == evento2.date.getTime()) 
            System.out.println("Warning! Two references pointing to the same object!");
         if (evento1.date.getTime() == null || evento2.date.getTime() == null)
             return 0;
         return evento1.date.getTime().compareTo(evento2.date.getTime());
    }

使用当前代码运行它应该会输出一堆警告。

另一则信息:根据JavadocComparator 中,如果参数之一为 null,则 Comparator#compare 应抛出 NullPointerException

<小时/>

解决方案 要解决此问题,您需要在每次调用 setEvento 时传递 Calendar 的不同实例。某些类(例如 Collection API 中的类)拥有复制构造函数,即将对象作为参数的构造函数,并返回一个具有完全相同的对象值(value)观。 Calendar 不实现复制构造函数,但它实现了 Cloneable 接口(interface),这意味着您可以克隆其对象。

克隆有时是frowned upon在 Java 世界中,但在这个特定情况下 it's a viable option .

以下是如何克隆 day ,以便每次调用 Evento 时,它都指向一个新对象(这是您的 listEventos1 方法):

list.add(setEvento(day, "Certain Tuesday", " do this "));
day = (Calendar) day.clone(); //This is what I added
day.add(Calendar.DAY_OF_MONTH, 1);

当然,对插入的每个对象重复此操作。

<小时/>

注意:顺便说一句,代码中的一些引号是英文右引号 (),而不是双引号 (")。这会破坏你的代码。

其他注意事项:您没有正确使用继承机制,并且可以通过使用 Evento 作为 Calendar 本身来简化您的代码。但这是另一天的事了。

关于java - Android - java - 如何通过 GregorianCalendar 参数对对象列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42544710/

相关文章:

python - 如何判断数组中是否只有一定数量的数字是连续的

java - 为什么 Java 中的原始数据类型不能是 "null"?

java - 从网页运行 Java 函数?

java - (Java) 如何在另一个程序的 Textfield/Textarea/Textlabel/... 中读/写文本

java - 将 json 文件解析为 imageButton

android - Android 上的 Neura SDK 实现

java - Android 从 Sqlite 数据库中保存并获取图像

python - 如何对 python 命令的输出进行排序?

r - 为大型数据集从 R 中的 data.frame 中获取前 N 个排序元素

MS Access 数据库的 Java 登录表单问题