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

时间:2019-07-19 14:28:46

标签: java sorting arraylist date-parsing java-date

我正在创建一个android应用程序,我需要根据日期对对象进行排序。日期以String的形式存储在客户对象中。我该怎么办?

我已经使用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;
       }
   };

我希望输出将按ArrayList进行排序,但不会根据日期进行排序。

我的日期格式为19.Jul.2019,但这给了我无法解析的异常。

6 个答案:

答案 0 :(得分:2)

java.time

使用 java.time 类代替麻烦的旧类(java.util.Datejava.sql.DateSimpleDateFormat)。 Android 26及更高版本随附了现代类的实现。

大多数 java.time 功能都已在ThreeTen-Backport项目中反向移植到Java 6和Java 7。在ThreeTenABP中进一步适用于较早的Android(<26)。参见How to use ThreeTenABP…

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;
        }
    }

}

答案 1 :(得分:1)

LocalDate作为您的财产

最好的解决方案是将您的Customer类更改为使用LocalDate类作为属性的类型。

提示:仅对date的成员字段使用更具描述性的名称。

public class Customer {
    public LocalDate firstContact ; 
    …
}

现在,您的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 ) ) ;
    }
};

如果您无法更改类属性的数据类型,请参见正确的Answer by Ezequiel

答案 2 :(得分:1)

ArrayList对String_Dates进行排序,并避免添加重复项。

在@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);
    }
}

使用自定义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);
    }
}

答案 3 :(得分:0)

按照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");
    }

答案 4 :(得分:0)

将o2与o1比较会以降序对列表进行排序。

您可以使用Collections.sort()以及list.sort()

我用客户对象创建了一个测试类。 希望这个例子会有所帮助。

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 + '\'' +
                    '}';
        }
    }

}

答案 5 :(得分:0)

我想问题在于如何比较两个字符串,这是一个有效的示例(升序)。

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:我的猜测是由于比较器内部的return 0,所以您的代码未排序。也许您的代码引发了异常,而您还没有看到控制台!