我正在实现一个简单的ListView,其中的数据源是一个包含名称、开始日期和结束日期的ArrayList。在iOS中,我会使用一个简单的NSPredicate来过滤数组,但在安卓和Java中,我不知道应该使用什么。欢迎任何建议。
发布于 2016-09-06 18:58:08
您可以使用Date.before和Date.after方法。它们允许您筛选日期列表(对于特定范围内的日期(例如,一月)):
a.使用Java 8筛选器,带有开始日期和结束日期。
b.使用Java循环/迭代器检查开始和结束日期。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.stream.Collectors;
public class FilterStartAndEndDate {
private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
private Collection<Date> dateList = null;
private Date start = null;
private Date end = null;
private FilterStartAndEndDate() throws ParseException {
dateList = new ArrayList<Date>() {{
add(sdf.parse("01/01/2016"));
add(sdf.parse("02/01/2016"));
add(sdf.parse("03/02/2016"));
add(sdf.parse("04/01/2016"));
add(sdf.parse("05/01/2016"));
}};
start = sdf.parse("31/12/2015");
end = sdf.parse("01/02/2016");
}
/**
* Filter dates with Lambda
*
* @throws ParseException
*/
private void getDatesBetweenStartAndFinishWithFilter() throws ParseException {
dateList.stream()
.filter(dates -> dates.after(start) && dates.before(end))
.collect(Collectors.toList())
.forEach(januaryDate->System.out.println(januaryDate));
}
/**
* Filter dates with Iterator
*
* @throws ParseException
*/
private void getDatesBetweenStartAndFinish() throws ParseException {
Collection<Date> datesInJanuaryList = new ArrayList<>();
for (Date eachDate : dateList) {
if (eachDate.after(start) && eachDate.before(end)) {
datesInJanuaryList.add(eachDate);
}
}
for (Date eachDate : datesInJanuaryList) {
System.out.println(eachDate);
}
}
public static void main(String[] args) throws Exception {
FilterStartAndEndDate datesInJanuary = new FilterStartAndEndDate();
datesInJanuary.getDatesBetweenStartAndFinish();
datesInJanuary.getDatesBetweenStartAndFinishWithFilter();
}
}
示例代码使用Lambda过滤器和Java迭代器过滤一月的日期。这两种方法都使用Date之前和之后的方法。
发布于 2018-09-16 06:29:44
定义一个类
包含名称、开始日期和结束日期
定义一个类来保存事件名称、开始日期和结束日期。
LocalDate
对日期-时间值使用现代的java.time类。LocalDate
类表示不带时间和时区的仅日期值。永远不要使用Date
、Calendar
、SimpleDateFormat
或其他糟糕的旧的遗留日期-时间类。
class Event {
String name;
LocalDate start, stop;
// Constructor
public Event ( String name , LocalDate start , LocalDate stop ) {
this.name = name;
this.start = start;
this.stop = stop;
}
}
添加一个方法,将传递的LocalDate
与开始和结束日期进行比较,如果包含在我们的日期范围内,则返回true。通常情况下,最好使用半开放方法进行比较,其中开始是包含的,而结束是排除的。
public boolean contains ( LocalDate localDate ) {
// Regarding the beginning date, a short way of saying2 "is equal to or is later than" is "is not before".
boolean x = ( ! localDate.isBefore( this.start ) ) && localDate.isBefore( this.stop );
return x;
}
创建这些事件的列表。
List< Event > events = new ArrayList<>();
events.add( new Event( "alpha" , LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.JANUARY , 28 ) ) );
events.add( new Event( "beta" , LocalDate.of( 2018 , Month.FEBRUARY , 23 ) , LocalDate.of( 2018 , Month.FEBRUARY , 28 ) ) );
events.add( new Event( "gamma" , LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.MARCH , 28 ) ) );
循环这些事件,检查每个事件是否包含我们的目标日期。
LocalDate target = LocalDate.of( 2018 , Month.FEBRUARY , 25 );
List< Event > hits = new ArrayList<>( events.size() );
for ( Event event : events ) {
if ( event.contains( target ) ) {
hits.add( event );
}
}
或者,使用带有lambda语法的Java Streams,而不是for-each循环。同样的效果;使用任何你喜欢的语法方法。
LocalDate target = LocalDate.of( 2018 , Month.FEBRUARY , 25 );
List< Event > hits =
events
.stream()
.filter( event -> event.contains( target ) )
.collect( Collectors.toList() )
;
为了演示,将所有这些放到一个大类中。我不会在实际工作中嵌套这个Event
类。
package com.basilbourque.example;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.List;
public class ListFilterExample {
public static void main ( String[] args ) {
ListFilterExample app = new ListFilterExample();
app.doIt();
}
private void doIt () {
List< Event > events = new ArrayList<>();
events.add( new Event( "alpha" , LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.JANUARY , 28 ) ) );
events.add( new Event( "beta" , LocalDate.of( 2018 , Month.FEBRUARY , 23 ) , LocalDate.of( 2018 , Month.FEBRUARY , 28 ) ) );
events.add( new Event( "gamma" , LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.MARCH , 28 ) ) );
LocalDate target = LocalDate.of( 2018 , Month.FEBRUARY , 25 );
List< Event > hits = new ArrayList<>( events.size() );
for ( Event event : events ) {
if ( event.contains( target ) ) {
hits.add( event );
}
}
System.out.println( hits );
}
class Event {
String name;
LocalDate start, stop;
public boolean contains ( LocalDate localDate ) {
// Regarding the beginning date, a short way of saying2 "is equal to or is later than" is "is not before".
boolean x = ( ! localDate.isBefore( this.start ) ) && localDate.isBefore( this.stop );
return x;
}
// Constructor
public Event ( String name , LocalDate start , LocalDate stop ) {
this.name = name;
this.start = start;
this.stop = stop;
}
@Override
public String toString () {
return "Event{ " +
"name='" + name + '\'' +
"| start=" + start +
"| stop=" + stop +
" }";
}
}
}
运行时。
事件{name=‘测试版’|开始=2018-02-23|停止=2018-02-28}
LocalDateRange
如果你想变得花哨,可以把ThreeTen-Extra库(下面讨论)添加到你的项目中。使用它的LocalDateRange
类将停止-开始日期对显式地表示为日期范围。该类已经包含了一个contains
方法,所以不需要编写自己的方法。
package com.basilbourque.example;
import org.threeten.extra.LocalDateRange;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ListFilterExample {
public static void main ( String[] args ) {
ListFilterExample app = new ListFilterExample();
app.doIt();
}
private void doIt () {
List< Event > events = new ArrayList<>();
events.add( new Event( "alpha" , LocalDate.of( 2018 , Month.JANUARY , 23 ) , LocalDate.of( 2018 , Month.JANUARY , 28 ) ) );
events.add( new Event( "beta" , LocalDate.of( 2018 , Month.FEBRUARY , 23 ) , LocalDate.of( 2018 , Month.FEBRUARY , 28 ) ) );
events.add( new Event( "gamma" , LocalDate.of( 2018 , Month.MARCH , 23 ) , LocalDate.of( 2018 , Month.MARCH , 28 ) ) );
LocalDate target = LocalDate.of( 2018 , Month.FEBRUARY , 25 );
// Lambda syntax, instead of for-each loop.
List< Event > hits = events.stream().filter( event -> event.contains( target ) ).collect( Collectors.toList() );
System.out.println( hits );
}
class Event {
String name;
LocalDateRange dateRange;
public boolean contains ( LocalDate localDate ) {
// Regarding the beginning date, a short way of saying2 "is equal to or is later than" is "is not before".
boolean x = this.dateRange.contains( localDate );
return x;
}
// Constructor
public Event ( String name , LocalDate start , LocalDate stop ) {
this.name = name;
this.dateRange = LocalDateRange.of( start , stop );
}
@Override
public String toString () {
return "Event{ " +
"name='" + name + '\'' +
"| dateRange=" + dateRange +
" }";
}
}
}
事件{name=‘测试版’| dateRange=2018-02-23/2018-02-28 }
关于java.time
框架内置于Java8和更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
现在在maintenance mode中的项目建议迁移到java.time类。
要了解更多信息,请参阅。和搜索堆栈溢出,以获得许多示例和解释。规范为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC driver。不需要字符串,也不需要java.sql.*
类。
从哪里获取java.time类?
中的
项目使用额外的类扩展了java.time。这个项目是未来可能添加到java.time中的试验场。您可能会在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
和more。
https://stackoverflow.com/questions/26075490
复制相似问题