使用Stream API查找相同日期并计数对象

bd1hkmkf  于 2022-10-01  发布在  Java
关注(0)|答案(2)|浏览(197)

我需要一些有关流API的帮助。我需要根据位置对对象列表进行分组,如果位置相同,但日期不同,而不考虑时间,则按1递增计数。我已经提供了带有getters、setter、data和预期输出的类的以下代码。

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<字符串,整数>Map的输出,其中字符串是位置和计数是基于日期。如果日期不同,则按1递增。时间在这里并不重要。我不确定如何使用流API或for循环对它们进行分组。

o/p: ["98.55.62.162":3 , "98.55.62.163":2]
vsdwdz23

vsdwdz231#

这是可能的,但有点棘手。检查一下这个

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()));
flseospp

flseospp2#

此答案基于the answer by Demian。我做了以下更改:

1.将Locale.ENGLISHDateTimeFormatter一起使用,这对于日期-时间值不是强制的,但强烈建议使用,因为日期-时间格式化/解析API对Locale敏感。
1.保持Event#date的类型为String,而我建议您在构造Event对象时使用LocalDateTime并解析字符串日期-时间字符串,就像Demian在他的回答中所做的那样。如果日、月、年、小时、分钟等具有单独的值,则可以使用LocalDateTime#of方法之一填充Event#date
1.使用.map(e -> LocalDateTime.parse(e.getDate(), formatter).toLocalDate()):在这个Map中,我首先将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: Date Time**了解有关modern date-time API的更多信息。

相关问题