我在FTP文件夹中的文件很少,其名称如下:
mainimport_31052017.csv
mainimport_21052017.csv
mainimport_15052017.csv
我有一个模式字符串:
String pattern =" mainimport_ddmmyyy";
现在我应该下载标题中包含最新日期的文件。我应该用Java 8好东西来做。
我有一个解决方案,但这还不够,我在2个语句中这样做:
1)我首先得到最新的日期:
Date newestDate = Collections.max(ftpFiles.stream().filter(fileName -> StringUtils.startsWith(fileName.getName(), prefix)).map(fileName -> {
String fileNameSuffix = fileName.getName().split("_")[1];
Date date = null;
try {
date = dateFormat.parse(fileNameSuffix);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}).collect(Collectors.toList()));
2)然后我获取最新日期的文件名:
Optional<FTPFile> file = ftpFiles.stream().filter(fileName->{
String fileNameSuffix = fileName.getName().split("_")[1];
Date date = null;
try {
date = dateFormat.parse(fileNameSuffix);
} catch (ParseException e) {
e.printStackTrace();
}
return StringUtils.startsWith(fileName.getName(), prefix) && date.equals(newestDate);
}).findFirst();
如果有可能的话,我试图在一个声明中做到这一点。
答案 0 :(得分:4)
假设日期始终具有指定的六个字符表示,您可以使用
Optional<FTPFile> max = ftpFiles.stream()
.filter(file -> file.getName().startsWith(prefix))
.max(Comparator.comparing(file -> file.getName()
.replaceFirst(".*_([0-9]{2})([0-9]{2})([0-9]{4}).*", "$3$2$1")));
工厂方法Comparator.comparing
允许您基于属性创建Comparator
,以便最大元素将是具有该属性的最大值的元素。
请注意,这只是将ddmmyyyy
格式化的日期转换为yyyymmdd
字符串,可以按字典顺序进行比较,只要日期和月份总是有两位数的形式,即领先零。
您可以通过准备和重用正则表达式模式来优化这一点:
Pattern pattern = Pattern.compile(".*_([0-9]{2})([0-9]{2})([0-9]{4}).*");
Optional<FTPFile> max = ftpFiles.stream()
.filter(file -> file.getName().startsWith(prefix))
.max(Comparator.comparing(file ->
pattern.matcher(file.getName()).replaceFirst("$3$2$1")));
如果DateFormat
是不可避免的先决条件,您可以使用
Optional<FTPFile> max = ftpFiles.stream()
.filter(file -> file.getName().startsWith(prefix))
.max(Comparator.comparing(file -> {
String name = file.getName();
name = name.substring(name.indexOf('_')+1);
try {
return dateFormat.parse(name);
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}));
这一次执行操作,但是缺点是在比较期间执行解析操作而不是必要的操作。如果你想避免这种情况,你可以采用原来的双通设计,但你仍然不需要收集到List
:
ftpFiles.stream()
.map(FTPFile::getName)
.filter(name -> name.startsWith(prefix))
.map(name -> {
name = name.substring(name.indexOf('_')+1);
try {
return dateFormat.parse(name);
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
})
.max(Comparator.naturalOrder())
.map(date -> prefix+'_'+dateFormat.format(date))
.flatMap(fileName -> ftpFiles.stream()
.filter(file -> file.getName().equals(fileName)).findAny())
.ifPresent(System.out::println);