【问题标题】:How to sort objects according to string date in java如何在java中根据字符串日期对对象进行排序
【发布时间】:2019-07-19 14:28:46
【问题描述】:

我正在创建一个需要根据日期对对象进行排序的 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,但它给了我无法解析的异常。

【问题讨论】:

  • 请提供一个完整的例子,数据和你的排序代码都没有。
  • 代码似乎没问题。你的日期相差多少。它们是否按天和月不同?
  • DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy"); LocalDate date1 = LocalDate.parse("12/02/2019", dtf); LocalDate date2 = LocalDate.parse("12/03/2019", dtf); System.out.println(date1.compareTo(date2));
  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的日期时间类现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…
  • 提示:重写 Customer 类以保存 LocalDate 对象,而不仅仅是字符串。

标签: java sorting arraylist date-parsing date


【解决方案1】:

java.time

使用 java.time 类来代替麻烦的遗留类(java.util.Datejava.sql.DateSimpleDateFormat)。现代类的实现随 Android 26 及更高版本提供。

大部分 java.time 功能都在 ThreeTen-Backport 项目中向后移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (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;
        }
    }

}

【讨论】:

  • 我在您的回答中添加了一些解释性文字。 Stack Overflow 不仅仅是一个剪断的集合。你应该对你的代码、它的动机和它的细节有一些解释。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      根据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");
          }
      

      【讨论】:

      • 请举例说明
      • 您所要做的就是更改格式字符串。这是最直接的。 @Anaskhan
      • 如示例中,您是否尝试使用SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      • 我仍然无法弄清楚。请您更改我给出的升序示例
      • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的日期时间类现在已被 java.time 类所取代。大多数 java.time 功能在 ThreeTen-Backport 项目中被反向移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我想问题在于你如何比较两个字符串,这是一个工作示例(按升序)。

        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。可能你的代码抛出了异常而你没有看到控制台!

        【讨论】:

        • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的日期时间类现在已被 java.time 类所取代。大多数 java.time 功能都在 ThreeTen-Backport 项目中向后移植到 Java 6 和 Java 7。进一步适用于ThreeTenABP 中的早期 Android (How to use ThreeTenABP…
        猜你喜欢
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 2010-11-11
        • 2013-01-05
        • 1970-01-01
        相关资源
        最近更新 更多