简体   繁体   English

如何在java中根据字符串日期对对象进行排序

[英]How to sort objects according to string date in java

I am creating an android application where I need to sort objects according to date.我正在创建一个 android 应用程序,我需要根据日期对对象进行排序。 The date is stored as a String in Customer Object.日期作为String存储在客户对象中。 How can I do it?我该怎么做?

I have already tried it using the Collection.sort() method but with no success.我已经使用Collection.sort()方法尝试过它,但没有成功。

public static Comparator<Customer> dateNewOld = new Comparator<Customer>() {
       @Override
       public int compare(Customer o1, Customer o2) {
           DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
           try
           {
               return f.parse(o2.date).compareTo(f.parse(o1.date));
           }
           catch (ParseException e)
           {
               e.printStackTrace();
           }
           return 0;
       }
   };

I expect the output to be sorted ArrayList but it doesn't get sorted according to date.我希望输出按 ArrayList 排序,但不会根据日期排序。

My Date Format is 19.Jul.2019 , but it's giving me Unparseable Exception.我的日期格式是19.Jul.2019 ,但它给了我无法解析的异常。

java.time时间

Use the java.time classes that supplant the troublesome legacy classes ( java.util.Date , java.sql.Date , SimpleDateFormat ).使用java.time类取代麻烦的遗留类( java.util.Datejava.sql.DateSimpleDateFormat )。 An implementation of the modern classes come with Android 26 and later.现代类的实现随 Android 26 及更高版本一起提供。

Most of the java.time functionality is back-ported to Java 6 & Java 7 in the ThreeTen-Backport project.ThreeTen-Backport项目中,大部分java.time功能都向后移植到 Java 6 和 Java 7。 Further adapted for earlier Android (<26) in ThreeTenABP .进一步适用于ThreeTenABP 中早期的 Android (<26)。 See How to use ThreeTenABP… .请参阅如何使用 ThreeTenABP...。

LocalDate represents a date-only value, without time-of-day and without time zone. LocalDate表示一个仅限日期的值,没有时间和时区。

package sortdates;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class SortDates {

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        Comparator<MyData> comparator = Comparator.comparing(myData -> LocalDate.parse(myData.date, formatter));
        List<MyData> set = getMyData().stream()
                .sorted(comparator)
                .collect(Collectors.toList());
        set.forEach(myData -> System.out.println(myData.date));
    }

    private static Collection<MyData> getMyData() {
        return Arrays.asList(
                new MyData("01/01/2000"),
                new MyData("01/02/2000"),
                new MyData("03/01/2002"),
                new MyData("04/06/2001")
                );
    }

    public static class MyData{
        String date;

        public MyData(String date) {
            this.date = date;
        }
    }

}

LocalDate as your property LocalDate作为您的财产

The best solution is to alter your Customer class to use LocalDate class as the type of your property.最好的解决方案是更改您的Customer类以使用LocalDate类作为您的财产类型。

Tip: Use a more descriptive name for your member fields that just date .提示:为仅date成员字段使用更具描述性的名称。

public class Customer {
    public LocalDate firstContact ; 
    …
}

Now your Comparator becomes quite simple, as the LocalDate class already implements the Comparable interface and its compareTo method.现在您的Comparator变得非常简单,因为LocalDate类已经实现了Comparable接口及其compareTo方法。

public static Comparator< Customer > CustomerComparator = new Comparator< Customer >() 
{
    @Override
    public int compare( Customer c1 , Customer c2 ) {
        return ( c1.firstContact.compareTo( c2.firstContact ) ) ;
    }
};

If you cannot change the data type of your class property, see the correct Answer by Ezequiel .如果您无法更改类属性的数据类型,请参阅Ezequiel的正确答案

ArrayList sorting String_Dates and avoiding duplicates on adding. ArrayList 排序 String_Dates 并避免添加时重复。

Adding a new example to @Ezequiel post.向@Ezequiel 帖子添加一个新示例。

public class ArrayListSet {
    static ArrayList<String> list =  new java.util.ArrayList<String>();
    public static void main(String[] args) {
        String inputDatess = "15.10.2020,11.10.2020,12.10.2020,12.10.2020,18.10.2020,13.10.2020,14.10.2020,11.10.2020,"
                + "15.10.2020,15.10.2020,15.10.2020,16.10.2020,17.10.2020,18.10.2020,19.10.2020,20.10.2020,10.10.2020";
        
        String[] dates = inputDatess.split(",");
        for (int i = 0; i < dates.length; i++) {
            listCustomAdd(dates[i]);
        }
        System.out.println("ArrayList with Custom Funciton for Add:\n"+list);
        
        ArrayList<String> listSorted = getSortedDatesStrList(list.stream());
        System.out.println("Sorted ArrayList:\n"+listSorted);
    }
    public static ArrayList<String> getSortedDatesStrList(Stream<String> stream) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        Comparator<String> comparator = Comparator.comparing(myData -> LocalDate.parse(myData, formatter));
        ArrayList<String> sortedList = (ArrayList<String>) stream
                .sorted(comparator)
                .collect(Collectors.toList());
        return sortedList;
    }
    public static void listCustomAdd(String dateStr) {
        if( !list.contains(dateStr) )
            list.add(dateStr);
    }
}

Example with Customed ArrayList to sort and avoid duplicates:使用自定义 ArrayList 排序和避免重复的示例:

public class CustomArrayListSet {
    //static ArrayList<String> predefinedList =  new java.util.ArrayList<String>();
    static ArrayListCustomStr<String> customList = new ArrayListCustomStr<String>();
    public static void main(String[] args) {
        String inputDatess = "15.10.2020,11.10.2020,12.10.2020,12.10.2020,18.10.2020,13.10.2020,14.10.2020,11.10.2020,"
                + "15.10.2020,15.10.2020,15.10.2020,16.10.2020,17.10.2020,18.10.2020,19.10.2020,20.10.2020,10.10.2020";
        
        String[] dates = inputDatess.split(",");
        for (int i = 0; i < dates.length; i++) {
            customList.add(dates[i]);
        }
        System.out.println("Custom ArrayList with override Add Function:\n"+customList);
        
        customList.sortDatesStrList();
        System.out.println("Sorted ArrayList:\n"+ customList );
    }
}
class ArrayListCustomStr<T> implements Set<T> {
    @Override
    public String toString() {
        StringBuffer buffer = new StringBuffer("[");
        for (int i = 0; i < entries.size(); i++) {
            buffer.append(entries.get(i));
            if ( (i+1) < entries.size() ) buffer.append(", ");
        }
        buffer.append("]");
        return buffer.toString();
    }
    public void sortDatesStrList() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        Comparator<String> comparator = Comparator.comparing(myData -> LocalDate.parse(myData, formatter));
        ArrayList<String> sortedList = (ArrayList<String>) entries.stream()
                .sorted(comparator)
                .collect(Collectors.toList());
        entries = sortedList;
    }
    private ArrayList<String> entries;
    // Simple constructor using an array list for its entries.
    public ArrayListCustomStr() {
        super();
        entries = new ArrayList<String>();
    }
    public int size() {
        return entries.size();
    }
    public void clear() {
        entries.clear();
    }
    public boolean isEmpty() {
        return entries.isEmpty();
    }
    public Object[] toArray() {
        return entries.toArray();
    }
    public boolean add(Object o) {
        // Ignore existing entries to ensure Set interface contract
        if (entries.contains(o))
            return false;

        return entries.add((String) o);
    }
    public boolean contains(Object o) {
        return entries.contains(o);
    }
    public boolean remove(Object o) {
        return entries.remove(o);
    }
    @SuppressWarnings("unchecked")
    public boolean addAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.addAll(c);
    }
    public boolean containsAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.containsAll(c);
    }
    public boolean removeAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.removeAll(c);
    }
    public boolean retainAll(@SuppressWarnings("rawtypes") Collection c) {
        return entries.retainAll(c);
    }
    @SuppressWarnings("unchecked")
    public Iterator<T> iterator() {
        return (Iterator<T>) entries.iterator();
    }
    @SuppressWarnings("unchecked")
    public Object[] toArray(Object[] a) {
        return entries.toArray(a);
    }
}

As per mkyong根据mkyong

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date1 = sdf.parse("2009-12-31");
    Date date2 = sdf.parse("2010-01-31");

    System.out.println("date1 : " + sdf.format(date1));
    System.out.println("date2 : " + sdf.format(date2));

    if (date1.compareTo(date2) > 0) {
        System.out.println("Date1 is after Date2");
    }

Comparing o2 with o1 will sort your list in descending order.将 o2 与 o1 进行比较将按降序对您的列表进行排序。

You can use Collections.sort() as well as list.sort()您可以使用 Collections.sort() 以及 list.sort()

I have created a test class with a customer object.我创建了一个带有客户对象的测试类。 Hope this example will help.希望这个例子会有所帮助。

package project;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class SortTest
{

    public static void main(String args[])
    {
        List<Customer> list = new ArrayList<>();
        list.add( new Customer( 1, "21/07/2019" ) );
        list.add( new Customer( 2, "19/06/2019" ) );
        list.add( new Customer( 3, "20/07/2019" ) );

        Collections.sort( list, dateNewOld );
        //list.sort( dateNewOld );

        print( list );
    }

    public static Comparator<Customer> dateNewOld = new Comparator<Customer>()
    {
        @Override
        public int compare( Customer o1, Customer o2 )
        {
            DateFormat f = new SimpleDateFormat( "dd/MM/yyyy" );
            try
            {
                return f.parse( o2.date ).compareTo( f.parse( o1.date ) );
            }
            catch ( ParseException e )
            {
                e.printStackTrace();
            }
            return 0;
        }
    };

    private static void print( List<Customer> list )
    {
        for ( Customer customer : list )
        {
            System.out.println(customer);
        }
    }

    static class Customer
    {
        final int id;
        final String date;

        Customer( int id, String date )
        {
            this.id = id;
            this.date = date;
        }

        @Override
        public String toString()
        {
            return "Customer{" +
                    "id=" + id +
                    ", date='" + date + '\'' +
                    '}';
        }
    }

}

I guess the problem is with how you compare the two Strings, here is a working example( in ascending order ).我想问题在于您如何比较两个字符串,这是一个工作示例(按升序排列)。

List<String> dateList = new ArrayList<>();
dateList.add("22/05/1995");
dateList.add("22/01/1995");
dateList.add("22/01/1994");
Comparator<String> dateNewOld = new Comparator<String>() {
  @Override
  public int compare(String o1, String o2) {
    DateFormat f = new SimpleDateFormat("dd/MM/yyyy");
    try {
      return f.parse(o1).compareTo(f.parse(o2));
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return 0;
  }
};
dateList.sort(dateNewOld);
System.out.println(dateList);

PS: My guess is that your code is not sorting because of return 0 inside the comparator. PS:我的猜测是您的代码没有排序,因为比较器内部return 0 Maybe your code is throwing an exception and you haven't seen console!也许您的代码正在抛出异常而您还没有看到控制台!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM