我有一个对象列表,其中有一个 LocalDateTime
领域。我想把所有这些对象非常 特地 每个日期和时间。
我解释一下应该如何做。
按日期降序排序 但是 按时间递增
下面是一个例子。
非排序 LocalDateTime
:
应该是按照这个顺序排序的 。
请记住,我需要用字段对一个对象进行排序,而不是用列表来排序 LocalDateTime
的对象列表,但是一个带有 LocalDateTime
领域。
谢谢你的帮助:)
LocalDateTime
对象知道如何按时间顺序排序。你想按日期降序排序(按时间倒序,以后的日期在前),但又想按时间日升序排序(按时间顺序),这意味着该类的内置功能实现了以下功能 compareTo
方法 Comparable
接口)无法完成工作。
对于自定义排序,请自行编写 Comparator
实现。该接口要求实现一个方法。compare
.
这里的逻辑很简单。
代码。
package work.basil.example;
import java.time.LocalDateTime;
import java.util.Comparator;
public class LocalDateTimeComparator implements Comparator < LocalDateTime >
{
@Override
public int compare ( LocalDateTime o1 , LocalDateTime o2 )
{
// Compare the date portion first. If equal, then look at time-of-day.
int result = o1.toLocalDate().compareTo( o2.toLocalDate() ); // Consider only the date portion first.
result = ( ( - 1 ) * result ); // Flip the positive/negative sign of the int, to get ascending order. Or more simply: `= - result ;`.
if ( 0 == result ) // If dates are equal, look at the time-of-day.
{
System.out.println( "reversing " );
result = o1.toLocalTime().compareTo( o2.toLocalTime() );
}
return result;
}
}
用这个比较器试试你的示例数据。
List < LocalDateTime > ldts = List.of(
LocalDateTime.parse( "2016-10-06T09:10" ) ,
LocalDateTime.parse( "2016-10-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T11:15" ) ,
LocalDateTime.parse( "2016-11-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T10:10" ) ,
LocalDateTime.parse( "2016-12-06T06:56" )
);
List < LocalDateTime > sorted = new ArrayList <>( ldts );
Comparator < LocalDateTime > comparator = new LocalDateTimeComparator();
sorted.sort( comparator );
转储到控制台。我们看到成功了。日期是按照2016年10月、11月和12月的日期顺序排列的,而时间-日期的
System.out.println( "ldts = " + ldts );
System.out.println( "sorted = " + sorted );
ldts = [2016-10-06T09:10, 2016-10-06T10:34, 2016-12-06T11:15, 2016-11-06T10:34, 2016-12-06T10:10, 2016-12-06T06:56] 。
排序=[2016-12-06T06:56, 2016-12-06T10:10, 2016-12-06T11:15, 2016-11-06T10:34, 2016-10-06T09:10, 2016-10-06T10:34] 。
该 评论者:Ole V.V. 展示了如何在现代Java中使用函数式lambda语法做等价的工作。这个评论启发了我去尝试函数式方法。
这里的想法是使用两个 Comparator
对象:一个用于日期,一个用于日期时间。我们可以嵌套一个 Comparator
内,实际上是通过调用 Comparator::thenComparing
. 所以我们需要建立两个比较器,然后将其中一个送入另一个。我们实例化一个 comparatorDate
然后喂那个人 comparatorTime
,以获得一个 comparatorDateThenTime
. 我们通过 comparatorDateThenTime
至 sort
方法,以实际得到执行的排序工作。
List < LocalDateTime > ldts = List.of(
LocalDateTime.parse( "2016-10-06T09:10" ) ,
LocalDateTime.parse( "2016-10-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T11:15" ) ,
LocalDateTime.parse( "2016-11-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T10:10" ) ,
LocalDateTime.parse( "2016-12-06T06:56" )
);
List < LocalDateTime > sorted = new ArrayList <>( ldts );
Comparator < LocalDateTime > comparatorDate =
Comparator
.comparing( ( LocalDateTime ldt ) -> ldt.toLocalDate() )
.reversed();
Comparator < LocalDateTime > comparatorTime =
Comparator
.comparing( ( LocalDateTime ldt ) -> ldt.toLocalTime() );
Comparator < LocalDateTime > comparatorDateThenTime =
comparatorDate
.thenComparing(
comparatorTime
);
sorted.sort( comparatorDateThenTime );
// Dump to console.
System.out.println( "ldts = " + ldts );
System.out.println( "sorted = " + sorted );
ldts = [2016-10-06T09:10,2016-10-06T10:34,2016-12-06T11:15,2016-11-06T10:34,2016-12-06T10:10,2016-12-06T06:56] 。
排序=[2016-12-06T06:56, 2016-12-06T10:10, 2016-12-06T11:15, 2016-11-06T10:34, 2016-10-06T09:10, 2016-10-06T10:34] 。
我们可以用匿名的单行本把它拉到一起。Comparator
对象的调用所返回的 Comparator.comparing
和 Comparator.reversed
.
List < LocalDateTime > ldts = List.of(
LocalDateTime.parse( "2016-10-06T09:10" ) ,
LocalDateTime.parse( "2016-10-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T11:15" ) ,
LocalDateTime.parse( "2016-11-06T10:34" ) ,
LocalDateTime.parse( "2016-12-06T10:10" ) ,
LocalDateTime.parse( "2016-12-06T06:56" )
);
List < LocalDateTime > sorted = new ArrayList <>( ldts );
sorted.sort(
Comparator
.comparing( ( LocalDateTime ldt ) -> ldt.toLocalDate() )
.reversed()
.thenComparing(
Comparator
.comparing( ( LocalDateTime ldt ) -> ldt.toLocalTime() )
)
);
// Dump to console.
System.out.println( "ldts = " + ldts );
System.out.println( "sorted = " + sorted );
ldts = [2016-10-06T09:10, 2016-10-06T10:34, 2016-12-06T11:15, 2016-11-06T10:34, 2016-12-06T10:10, 2016-12-06T06:56] 。
排序=[2016-12-06T06:56, 2016-12-06T10:10, 2016-12-06T11:15, 2016-11-06T10:34, 2016-10-06T09:10, 2016-10-06T10:34] 。
我想我更希望在生产代码中看到第一种,即多线的那一种。但我不确定。
问题中所说的真正问题涉及到一个 LocalDateTime
作为另一个类的成员字段。所以,让我们把我们的解决方案扩展到包括那个嵌套类。这里我们发明了一个 Happening
类,由一个描述字符串和一个 LocalDateTime
对象。
package work.basil.example;
import java.time.LocalDateTime;
import java.util.Objects;
public class Happening
{
private String description;
private LocalDateTime localDateTime;
public Happening ( String description , LocalDateTime localDateTime )
{
this.description = Objects.requireNonNull( description );
this.localDateTime = Objects.requireNonNull( localDateTime );
}
public String getDescription ( ) { return this.description; }
public LocalDateTime getLocalDateTime ( ) { return this.localDateTime; }
@Override
public String toString ( )
{
return "Happening{ " +
"description='" + description + '\'' +
" | localDateTime=" + localDateTime +
" }";
}
}
让我们把这些对象做成一个集合,并使用类似上面看到的代码进行排序。我们必须多走一步,提取一个叫做 LocalDateTime
的对象,从每个 Happening
对象。
List < Happening > happenings = List.of(
new Happening( "aaa" , LocalDateTime.parse( "2016-10-06T09:10" ) ) ,
new Happening( "bbb" , LocalDateTime.parse( "2016-10-06T10:34" ) ) ,
new Happening( "ccc" , LocalDateTime.parse( "2016-12-06T11:15" ) ) ,
new Happening( "ddd" , LocalDateTime.parse( "2016-11-06T10:34" ) ) ,
new Happening( "eee" , LocalDateTime.parse( "2016-12-06T10:10" ) ) ,
new Happening( "fff" , LocalDateTime.parse( "2016-12-06T06:56" ) )
);
List < Happening > sorted = new ArrayList <>( happenings );
sorted.sort(
Comparator
.comparing( ( Happening happening ) -> happening.getLocalDateTime().toLocalDate() )
.reversed()
.thenComparing(
Comparator
.comparing( ( Happening happening ) -> happening.getLocalDateTime().toLocalTime() )
)
);
// Dump to console.
System.out.println( "happenings = " + happenings );
System.out.println( "sorted = " + sorted );
当运行时,我们从a-b-c-d-e-f到f-e-c-d-a-b的顺序。
happenings = [Happening{ description='aaa'