我有一个列表List,在以下两种情况下,需要编写基于流的通用代码来过滤出对象。
输入参数为dp,值为“ MAR 2019”。如果找到任何匹配的行,并且结束日期不为null,则返回该行。
输入:
[PT(pn=1, endDate=2019-01-11, dp=MAR 2019),
PT(pn=4, endDate=null, dp=APR 2019),
PT(pn=6, endDate=2019-05-11, dp=MAY 2019)]
输出:
PT(pn=1, endDate=2019-01-11, dp=MAR 2019)}
该功能的参数为“ MAR 2019”。如果找到任何匹配的行且结束日期为null,则需要返回所有记录,直到获得非空的结束日期
输入:
[PT(pn=1, endDate=null, dp=MAR 2019),
PT(pn=4, endDate=2019-04-11, dp=APR 2019),
PT(pn=6, endDate=2019-05-11, dp=MAY 2019)]
输出:
[PT(pn=1, endDate=null, dp=MAR 2019),
PT(pn=4, endDate=2019-04-11, dp=APR 2019)]
class PT{
Integer pn;
Date endDate;
String dp;
}
List<PT> filteredList11 = availablePT.get()
.stream()
.sorted(Comparator.comparing(PT::getPn))
.filter(e->)
.collect(Collectors.toList());
对于在上述情况下如何编写一个过滤函数,我有点困惑,因为我们从来没有在使用流时捕获任何先前的状态值,请注意。
答案 0 :(得分:0)
这里是一种方法的示例,该方法可以在问题的第一部分中完成您想做的事情。基本上,这仅使用一条List<PT>
语句来流式处理和过滤给定的.filter
:
public class StackoverflowMain {
static class PT {
Integer pn;
// Here, I changed your code. You should really use the up-to-date time API
LocalDate endDate;
String dp;
public PT(int pn, LocalDate endDate, String dp) {
this.pn = pn;
this.endDate = endDate;
this.dp = dp;
}
}
/**
* <p>
* Gets a list of all PTs that match the given criterium for the dp class
* attribute of class PT.
* </p>
*
* @param source the original list that needs to be filtered
* @param dp the dp value to be matched
* @return a list of all PTs that passed the filter criterium
*/
public static List<PT> getPTWithValidEndDateAndDp(List<PT> source, String dp) {
return source.stream()
.filter(pt -> pt.endDate != null && pt.dp.equals(dp))
.collect(Collectors.toList());
}
public static void main(String args[]) {
// mock the list of PTs that you receive from somewhere
List<PT> receivedPTs = new ArrayList<PT>();
// one PT with endDate == null but matching dp
receivedPTs.add(new PT(1, null, "MAR 2019"));
// one PT with valid endDate and valid dp, but no matching dp
receivedPTs.add(
new PT(4, LocalDate.parse("2019-04-11", DateTimeFormatter.ISO_DATE), "APR 2019")
);
// another totally valid PT whose dp does not match
receivedPTs.add(
new PT(6, LocalDate.parse("2019-05-11", DateTimeFormatter.ISO_DATE), "MAY 2019")
);
// a totally valid PT with the matching dp ---> should be contained in the output
receivedPTs.add(
new PT(1, LocalDate.parse("2019-03-11", DateTimeFormatter.ISO_DATE), "MAR 2019")
);
// create a list from the valid and matching PTs passing the source list and the
// dp to be matched
List<PT> marchPTs = getPTWithValidEndDateAndDp(receivedPTs, "MAR 2019");
// output the result
marchPTs.forEach(mpt -> System.out.println("[pn: " + mpt.pn + ", endDate: "
+ mpt.endDate.format(DateTimeFormatter.ISO_DATE) + ", dp: " + mpt.dp + "]"));
}
}
请注意,我更改了代码的一部分,将
java.util.Date
的老式且容易出错的用法替换为java.time.LocalDate
,这在当今应是首选。
我不知道我是否有足够的时间为您的第二个要求提供示例,但我会尝试…
答案 1 :(得分:0)
第1部分:
public static List<PT> filterOne(List<PT> input, String dp)
{
return input.stream()
.filter(pt -> pt.endDate != null && pt.dp.equals(dp))
.collect(Collectors.toList());
}
第2部分:
public static List<PT> filterTwo(List<PT> input, String dp)
{
AtomicBoolean dpFilter = new AtomicBoolean(false);
return input.stream()
.filter(obj -> {
if (dpFilter.get()){
if (obj.endDate == null || obj.dp.equals(dp)) {
dpFilter.set(false);
return false;
}
return true;
}
if (obj.endDate == null && obj.dp.equals(dp)){
dpFilter.set(true);
return true;
}
return false;
})
.collect(Collectors.toList());
}