使用Java8是否可以一步创建一个列表或任何其他数据结构(分组、排序和计数)?
我有一个具有此结构的文件: a, City1, 2013-09-05 14:08:15 b, City2, 2015-10-08 16:10:15 c, City2, 2010-09-05 14:08:15 d, City1, 2011-09-05 14:08:15 a、 2013-09-05 14:08:15第1城市 b、 城市2,2015-10-08 16:10:15 c、 城市2,2010-09-05 14:08:15 d、 2011-09-05 14:08:15城市1 它是以逗号分隔的值和以行尾字符分隔的行 我需要在Java8中创建一个数据结构,在该结构中,我按城市对行进行分组,并在每个这样的组中按日期升序排序,并计算每个组中的行数 我试过:使用Java8是否可以一步创建一个列表或任何其他数据结构(分组、排序和计数)?,java,java-8,Java,Java 8,我有一个具有此结构的文件: a, City1, 2013-09-05 14:08:15 b, City2, 2015-10-08 16:10:15 c, City2, 2010-09-05 14:08:15 d, City1, 2011-09-05 14:08:15 a、 2013-09-05 14:08:15第1城市 b、 城市2,2015-10-08 16:10:15 c、 城市2,2010-09-05 14:08:15 d、 2011-09-05 14:08:15城市1 它是以逗号分隔的值
列表
地图
,该地图按城市分组,并按日期对每组进行排序地图
,用于按城市和行数分组public PhotoResponse processFile() {
//read each line of the file and create a new object PhotoIn for each one
List<PhotoIn> lista = null;
try {
lista = Files.lines(Paths.get(file))
.map(line -> line.split(","))
.map(photo -> new PhotoIn(photo[0].substring(0, photo[0].lastIndexOf(".")), photo[0].substring(photo[0].lastIndexOf(".") + 1 ), photo[1].trim(), parseDate(photo[2]), index++))
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
return generateOutput(lista);
}
private PhotoResponse generateOutput(List<PhotoIn> photos) {
//Grouping photos by city
Map<String, List<PhotoIn>> photosByCity = photos.stream().collect(Collectors.groupingBy(PhotoIn::getCity));
//Sorting photos by date into each city
photosByCity.values().forEach(list -> list.sort(Comparator.comparing(PhotoIn::getDate)));
//Grouping photos by city and amount
Map<String, Long> numeroPorCiudades = photos.stream().collect(Collectors.groupingBy(PhotoIn::getCity, Collectors.counting()));
List<PhotoOut> photoOutList = new ArrayList<PhotoOut>();
photosByCity.forEach((key, list) -> {
String digits = Integer.toString(Long.toString(numeroPorCiudades.get(key)).length());
counter = 1;
list.forEach(photoIn -> {
photoOutList.add(new PhotoOut(photoIn.getName() + "." + photoIn.getExtension(), key + String.format("%0" + digits + "d", counter++) + "." + photoIn.getExtension(), photoIn.getIndex()));
});
});
return sortOutput(photoOutList);
}
公共光响应处理文件(){
//读取文件的每一行,并为每一行创建一个新对象PhotoIn
List lista=null;
试一试{
lista=Files.lines(path.get(file))
.map(直线->直线分割(“,”)
.map(photo->new PhotoIn(photo[0]。子字符串(0,photo[0]。lastIndexOf(“.”),photo[0]。子字符串(photo[0]。lastIndexOf(“.”+1),photo[1]。trim(),parseDate(photo[2]),index++)
.collect(Collectors.toList());
}捕获(IOE异常){
e、 printStackTrace();
}
返回生成输出(lista);
}
专用光响应生成输出(列表照片){
//按城市分组照片
Map photosByCity=photos.stream().collect(Collectors.groupingBy(PhotoIn::getCity));
//按日期将照片分类到每个城市
forEach(list->list.sort(Comparator.comparing(PhotoIn::getDate));
//按城市和数量分组照片
Map numeroPorCiudades=photos.stream().collect(Collectors.groupingBy(PhotoIn::getCity,Collectors.counting());
List photoOutList=new ArrayList();
photosByCity.forEach((键,列表)->{
字符串位数=Integer.toString(Long.toString(numerioporciudades.get(key)).length());
计数器=1;
列表。forEach(照片输入->{
photoOutList.add(新的PhotoOut(photoIn.getName()+“+photoIn.getExtension(),键+字符串.格式(“%0”+数字+“d”,计数器++)+“+photoIn.getExtension(),photoIn.getIndex()));
});
});
返回排序输出(photoOutList);
}
我正在解决这个问题,但我正在寻找一种更好、更有效的方法来使用Java8是否可以在一个步骤中完成这三个步骤?。我需要的是将所有信息分组到一个数据结构中。使用该模型:
class Model {
private String title;
private String city;
private LocalDateTime date;
}
可以这样做:
List<Model> list = getFromFile();
Comparator<Model> comparator = Comparator.comparing(Model::getDate);
//grouping the list by City with lists sorted by date
Map<String, List<Model>> map = list.stream()
.collect(
Collectors.groupingBy( //grouping the list by City with lists
m -> m.getCity(),
Collectors.collectingAndThen(Collectors.toList(), l->{
l.sort(comparator);
return l;
})
)
);
//getting another map with counts
Map<String, Object> countMap = map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().size()));
List List=getFromFile();
Comparator Comparator=Comparator.comparing(Model::getDate);
//使用按日期排序的列表按城市对列表进行分组
Map=list.stream()
.收集(
Collectors.groupingBy(//使用列表按城市对列表进行分组
m->m.getCity(),
Collectors.collectionAndThen(Collectors.toList(),l->{
l、 排序(比较器);
返回l;
})
)
);
//获取另一张带有计数的地图
Map countMap=Map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,Entry->Entry.getValue().size());
对于该型号:
class Model {
private String title;
private String city;
private LocalDateTime date;
}
可以这样做:
List<Model> list = getFromFile();
Comparator<Model> comparator = Comparator.comparing(Model::getDate);
//grouping the list by City with lists sorted by date
Map<String, List<Model>> map = list.stream()
.collect(
Collectors.groupingBy( //grouping the list by City with lists
m -> m.getCity(),
Collectors.collectingAndThen(Collectors.toList(), l->{
l.sort(comparator);
return l;
})
)
);
//getting another map with counts
Map<String, Object> countMap = map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().size()));
List List=getFromFile();
Comparator Comparator=Comparator.comparing(Model::getDate);
//使用按日期排序的列表按城市对列表进行分组
Map=list.stream()
.收集(
Collectors.groupingBy(//使用列表按城市对列表进行分组
m->m.getCity(),
Collectors.collectionAndThen(Collectors.toList(),l->{
l、 排序(比较器);
返回l;
})
)
);
//获取另一张带有计数的地图
Map countMap=Map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,Entry->Entry.getValue().size());
分享您的解决方案。到目前为止,您得到了什么?解决方案大概将由I/O主导。聪明的人可能更容易理解。选择单行程序,可能是收集器。使用TreeSet
收集器按收集器分组。行数只是在集合
上调用大小
。请不要删除您发布的代码,因为这样做可能会使现有答案无效。顺便说一下,您的城市和日期字符串前面会有一个空格。在,
(逗号+空格)上拆分,而不是,
。或者事后再打电话。@BasilBourque谢谢。这只是目前代码的预览。我已经做了一些更正。请分享您的解决方案。到目前为止,您得到了什么?解决方案大概将由I/O主导。聪明的人可能更容易理解。选择单行程序,可能是收集器。使用TreeSet
收集器按收集器分组。行数只是在集合
上调用大小
。请不要删除您发布的代码,因为这样做可能会使现有答案无效。顺便说一下,您的城市和日期字符串前面会有一个空格。在,
(逗号+空格)上拆分,而不是,
。或者事后再打电话。@BasilBourque谢谢。这只是目前代码的预览。我已经做了一些修正。@icj03刚刚测试过,一切对我来说都很好,我甚至没有任何来自Intellij想法的警告。我不知道,可能是某个jvm特定的问题。我使用的是1.8.0Ó我实际上讨厌旧的API,但这不是问题所在。编辑了LocalDateTime的答案,它根本没有影响算法。如果先排序,然后分组,而不使用Collectors::collecting,则会得到完全相同的结果,然后@icj03刚刚对其进行了测试,对我来说一切正常,我的Intellij想法甚至没有任何警告。我不知道,可能是某个jvm特定的问题。我使用的是1.8.0Ó我实际上讨厌旧的API,但它不是