Android - 如何按日期对arrayList进行排序?

时间:2017-07-12 05:51:05

标签: java android sorting arraylist

我正在尝试按日期对arrayList进行排序。我每次收到通知时都会将日期存储在Firebase上,并从那里检索。我正在使用Collections.sort但我不知道如何实现我的代码,因为我的日期格式以字符串格式开头,例如“2017年7月12日上午12:00”。

我在stackoverflow上看到过这方面的一些例子,但我不知道如何让它在我的情况下工作。我将在下面发布截图和我的代码。

日期未排序。

enter image description here

NotificationFragment.java

public class NotificationFragment extends Fragment {
        prepareNotification1();
        sortDate();
        return v;
    }

       private void prepareNotification1() {
            FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
            String userID = user.getUid();

  mRef.child("customers").child(userID).child("Notification").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    Notification menu = dataSnapshot.getValue(Notification.class);
                    notificationList.add(menu);
                mAdapter.notifyDataSetChanged();
            }
 });
    }

    public void sortDate() {
        Collections.sort(notificationList, new Comparator<Notification>() {
            @Override
            public int compare(Notification lhs, Notification rhs) {
                return lhs.getDate().compareTo(rhs.getDate());
            }
        });
        mAdapter = new NotificationAdapter(getContext(), notificationList);
        mRecyclerView.setAdapter(mAdapter);
    }
}

MyFirebaseMessagingService.java

public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Calendar cal = Calendar.getInstance();

        String currentDateTimeString = DateFormat.getDateInstance().format(new Date());

        SimpleDateFormat df = new SimpleDateFormat("hh:mm a");
        String currentTime = df.format(cal.getTime());

        String notificationTime = currentDateTimeString + " at " + currentTime;

        Notification newNotification = new Notification(remoteMessage.getData().get("body"), notificationTime);
        mRef.child("customers").child(userID).child("Notification").push().setValue(newNotification);
}

Notification.java

public class Notification {
    private String message;
    private String date;


    public Notification(){
    }

    public Notification(String message, String date){
        this.message = message;
        this.date = date;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

6 个答案:

答案 0 :(得分:5)

考虑将日期存储在Notification long(unix时间)或DateLocalDateTime,如果您正在使用Java 8支持)并将其格式化为仅在将字符串显示到UI时才显示字符串。

答案 1 :(得分:2)

您可以简单地将日期时间字符串解析为 LocalDateTime 并执行自然排序。

使用 Stream

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d MMM u 'at' h:m a", Locale.UK);
        
        Stream.of(
                    "10 Jul 2017 at 10:59 pm",
                    "10 Jul 2017 at 10:59 pm",
                    "11 Jul 2017 at 11:15 pm",
                    "9 Jul 2017 at 11:15 pm"
                )
                .map(s -> LocalDateTime.parse(s, dtf))
                .sorted()
                .forEach(dt -> System.out.println(dtf.format(dt)));
    }
}

输出:

9 Jul 2017 at 11:15 pm
10 Jul 2017 at 10:59 pm
10 Jul 2017 at 10:59 pm
11 Jul 2017 at 11:15 pm

Stream解决方案:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d MMM u 'at' h:m a", Locale.UK);
        List<LocalDateTime> listLdt = new ArrayList<>();
        
        List<String> listDtStr = 
                Arrays.asList(
                                "10 Jul 2017 at 10:59 pm",
                                "10 Jul 2017 at 10:59 pm",
                                "11 Jul 2017 at 11:15 pm",
                                "9 Jul 2017 at 11:15 pm"
                            );
        
        // Add the strings, parsed into LocalDateTime, to listLdt
        for(String s: listDtStr) {
            listLdt.add(LocalDateTime.parse(s, dtf));
        }
        
        // Sort listLdt
        Collections.sort(listLdt);
        
        // Display
        for(LocalDateTime ldt: listLdt) {
            System.out.println(ldt.format(dtf));
        }
    }
}

输出:

9 Jul 2017 at 11:15 pm
10 Jul 2017 at 10:59 pm
10 Jul 2017 at 10:59 pm
11 Jul 2017 at 11:15 pm

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

使用旧的日期时间 API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        final SimpleDateFormat sdf = new SimpleDateFormat("d MMM u 'at' h:m a", Locale.UK);
        List<Date> listDate = new ArrayList<>();
        
        List<String> listDtStr = 
                Arrays.asList(
                                "10 Jul 2017 at 10:59 pm",
                                "10 Jul 2017 at 10:59 pm",
                                "11 Jul 2017 at 11:15 pm",
                                "9 Jul 2017 at 11:15 pm"
                            );
        
        // Add the strings, parsed into LocalDateTime, to listDate
        for(String s: listDtStr) {
            listDate.add(sdf.parse(s));
        }
        
        // Sort listDate
        Collections.sort(listDate);
        
        // Display
        for(Date date: listDate) {
            System.out.println(sdf.format(date));
        }
    }
}

输出:

9 Jul 4 at 11:15 pm
10 Jul 5 at 10:59 pm
10 Jul 5 at 10:59 pm
11 Jul 6 at 11:15 pm

注意java.util 日期时间 API 及其格式 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API*


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 2 :(得分:1)

解析日期后进行排序。

Collections.sort(notificationList, new Comparator<Notification>() {
            DateFormat f = new SimpleDateFormat("dd/MM/yyyy '@'hh:mm a");
            @Override
            public int compare(Notification lhs, Notification rhs) {
                try {
                    return f.parse(lhs.getDate()).compareTo(f.parse(rhs.getDate()));
                } catch (ParseException e) {
                    throw new IllegalArgumentException(e);
                }
            }
        })

如果您的日期采用其他格式,请相应地写下 DateFormat

答案 3 :(得分:1)

据我了解,Notification.getDate()返回String值。所以,使用

public static Date toDate(String value) throws ParseException {
    DateFormat format = new SimpleDateFormat("d MMMM yyyy 'at' HH:mm'am'", Locale.ENGLISH);
    return format.parse(value);
}

此方法从String中删除Date。只需获取两个日期并使用Date.compareTo方法。

date1 = toDate(lhs.getDate());
date2 = toDate(rhs.getDate());
date1.compareTo(date2);

答案 4 :(得分:0)

而不是在通知模型中设置如下的日期。

`String notificationTime = currentDateTimeString + " at " + currentTime;`

您可以将时间保存为 System.currentTimeinMillis(); ,然后在显示时将其解析为日期,如下所示

DateFormat f = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
f.parse(timeStamp);

答案 5 :(得分:0)

按日期按升序和降序对 ArrayList 进行排序

在我的回答中,我将使用 ArrayList 来表示名为 debtsArrayList 的债务。此答案将展示如何按 ArrayListdate 顺序按 ascending 对带有对象的 descending 进行排序。

排序比较器类

首先创建一个 SortComparator 类来保存按 ascendingdescending 顺序按日期排序的函数。

public class SortComparator {

    /**
     * Class to sort list by Date
     */
    public static class SortBy_Date {

        /**
         * Class to sort list by Date in ascending order
         */
        public static class Ascending implements Comparator<JB_Debts> {

            @Override
            public int compare(JB_Debts jbDebts1, JB_Debts jbDebts2) {

                // Create DateFormat
                DateFormat dateFormat = DateFormat.getDateInstance(
                        DateFormat.FULL, Locale.ENGLISH);

                // Catch Parse errors
                try {

                    // Parse dates
                    Date date1 = dateFormat.parse(jbDebts1.getDate());
                    Date date2 = dateFormat.parse(jbDebts2.getDate());

                    // Check if dates are null
                    if ((date1 != null) && (date2 != null)) {

                        // Ascending
                        return (date1.getTime() > date2.getTime() ? 1 : -1);

                    } else {

                        return 0; // Return 0 to leave it at current index
                    }
                } catch (Exception exception) {

                    exception.printStackTrace();
                }

                return 0;
            }
        }

        /**
         * Class to sort list by Date in descending order
         */
        public static class Descending implements Comparator<JB_Debts> {

            @Override
            public int compare(JB_Debts jbDebts1, JB_Debts jbDebts2) {

                // Create DateFormat
                DateFormat dateFormat = DateFormat.getDateInstance(
                        DateFormat.FULL, Locale.ENGLISH);

                // Catch Parse and NullPointerExceptions
                try {

                    // Parse dates
                    Date date1 = dateFormat.parse(jbDebts1.getDate());
                    Date date2 = dateFormat.parse(jbDebts2.getDate());

                    // Check if dates are null
                    if ((date1 != null) && (date2 != null)) {

                        // Descending
                        return (date1.getTime() > date2.getTime() ? -1 : 1);

                    } else {

                        return 0; // Return 0 to leave it at current index
                    }
                } catch (Exception exception) {

                    exception.printStackTrace();
                }

                return 0;
            }
        }
    }
}

在我的示例中,我使用带有对象 ArrayList<JB_Debts> 的 ArrayList,其中 JB_Debts 是我的 Java bean 类,带有 getter 和 setter 方法。

    public class JB_Debts {

    private String date; // Our date string

    /**
     * Default constructor
     */
    public JB_Debts2() {
    }

    /**
     * Function to get date
     */
    public String getDate() {

        return date;
    }

    /**
     * Function to set date
     *
     * @param date - Date
     */
    public void setDate(String date) {

        this.date = date;
    }
}

将类与集合一起使用

然后,我们将使用这个类和 Java 集合来对我们的 ArrayList 和基于日期的对象进行升序和降序排序。

// Create ArrayList
ArrayList<JB_Debts> debtsArrayList = new ArrayList();

Collections.sort(debtsArrayList,
            new SortComparator.SortBy_Date.Ascending());

Collections.sort(debtsArrayList,
            new SortComparator.SortBy_Date.Descending());

注意

请注意,我将日期作为字符串存储在我的 ArrayList 中。为了对它们进行排序,我将字符串解析为如下所示:

// Create DateFormat with Locale
DateFormat dateFormat = DateFormat.getDateInstance(
                DateFormat.FULL, Locale.ENGLISH);

// Create DateFormat without Locale
DateFormat dateFormat = DateFormat.getDateInstance(
                DateFormat.FULL);

您可以将 DateFormat.FULL 替换为您选择的日期格式,例如"dd/MM/yyyy hh:mm a" 然后如下所示:

// Create DateFormat with Locale
DateFormat dateFormat = new SimpleDateFormat(
            "dd/MM/yyyy hh:mm a", Locale.ENGLISH);

// Create DateFormat without Locale
DateFormat dateFormat = new SimpleDateFormat(
            "dd/MM/yyyy hh:mm a");

希望能帮到你