我需要一些有关 Stream API 的帮助。我需要根据位置对对象列表进行分组,如果位置相同但日期不同(无论时间如何),则将计数增加 1。 我为带有 getter setter 和数据以及预期输出的类提供了以下代码。
public class Event {
String location;
String date;
String count;
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public String getLocation() {
return location;
}
public String getDate() {
return date;
}
public void setLocation(String location) {
this.location = location;
}
public void setDate(String date) {
this.date = date;
}
}
事件类数据:
Event event = new Event();
event.setLocation("98.55.62.162");
event.setDate("09/17/2022 12:05:43 PM");
event.add(event);
event.setLocation("98.55.62.162");
event.setDate("09/16/2022 12:05:45 PM");
event.add(event);
event.setLocation("98.55.62.162");
event.setDate("09/16/2022 12:05:47 PM");
event.add(event);
event.setLocation("98.55.62.162");
event.setDate("09/15/2022 12:05:49 PM");
event.add(event);
event.setLocation("98.55.62.163");
event.setDate("09/17/2022 12:05:31 PM");
event.add(event);
event.setLocation("98.55.62.163");
event.setDate("09/16/2022 12:05:22 PM");
event.add(event);
event.setLocation("98.55.62.163");
event.setDate("09/16/2022 12:05:11 PM");
event.add(event);
我试着做
Map<String, List<Event>>
Map<String, List<Event>> eventMap = events.stream().collect(Collectors.groupingBy(s -> s.getLocation()));
这对我不起作用。
我需要像这样的输出
Map
o/p: ["98.55.62.162":3 , "98.55.62.163":2]
这个答案基于 Demian 的答案。我做了以下更改:
Locale.ENGLISH
与 DateTimeFormatter
一起使用,这对于您的日期时间值不是强制的,但强烈建议使用,因为日期时间格式化/解析 API 是 Locale
敏感的。Event#date
的类型保留为 String
,同时我建议您使用 LocalDateTime
并在构造 Event
对象时解析字符串日期时间字符串,就像 Demian 在他的答案中所做的那样。如果您有单独的日、月、年、小时、分钟等值,则可以使用 LocalDateTime#of
方法之一来填充 Event#date
。.map(e -> LocalDateTime.parse(e.getDate(), formatter).toLocalDate())
的使用:在此映射中,我首先将Event#date
解析为LocalDateTime
,然后使用LocalDateTime#toLocalDate
List<Event> events = new ArrayList<>();
Event event = new Event();
event.setLocation("98.55.62.162");
event.setDate("09/17/2022 12:05:43 PM");
events.add(event);
...
...
...
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a", Locale.ENGLISH);
Map<String, Long> eventMap = events
.stream()
.collect(
Collectors.groupingBy(Event::getLocation))
.entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey, v -> v.getValue()
.stream()
.map(e -> LocalDateTime.parse(e.getDate(), formatter).toLocalDate())
.distinct()
.count()));
System.out.println(eventMap);
输出:
{98.55.62.163=2, 98.55.62.162=3}
从 Trail:日期时间了解有关 现代日期时间 API 的更多信息。
这是可能的,但有点棘手。检查一下:
Event event = new Event();
List<Event> events = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/d/yyyy hh:mm:ss a");
event.setLocation("98.55.62.162");
event.setDate(LocalDate.parse("09/17/2022 12:05:43 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.162");
event.setDate(LocalDate.parse("09/16/2022 12:05:45 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.162");
event.setDate(LocalDate.parse("09/16/2022 12:05:47 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.162");
event.setDate(LocalDate.parse("09/15/2022 12:05:49 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.163");
event.setDate(LocalDate.parse("09/17/2022 12:05:31 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.163");
event.setDate(LocalDate.parse("09/16/2022 12:05:22 PM", formatter));
events.add(event);
event = new Event();
event.setLocation("98.55.62.163");
event.setDate(LocalDate.parse("09/16/2022 12:05:11 PM", formatter));
events.add(event);
Map<String, Long> eventMap = events
.stream()
.collect(
Collectors.groupingBy(Event::getLocation)
).entrySet()
.stream()
.collect(Collectors.toMap(
Map.Entry::getKey, v -> v.getValue()
.stream()
.map(e -> e.getDate())
.distinct()
.count()));