[英]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
,但它给了我无法解析的异常。
Use the java.time classes that supplant the troublesome legacy classes ( java.util.Date
, java.sql.Date
, SimpleDateFormat
).使用java.time类取代麻烦的遗留类(
java.util.Date
、 java.sql.Date
、 SimpleDateFormat
)。 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);
}
}
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.