如何根据Java的小时间隔重复列出列表?

发布于 2025-02-13 18:52:05 字数 746 浏览 1 评论 0 原文

首先,我有这个对象,我称之为 myObject ;

public class MyObject{
    private google.protobuf.Timestamp timestamp;
    private String description;
}

然后我有此列表:

List<MyObject> myList = new ArrayList<>();

现在让我们想象 myList 包含500个项目。我想要的是消除同一小时内发生的重复(相同的描述)。

因此,在同一小时内,列表中不应在列表中存在两个不同的项目。如果他们这样做,我们只想保留一个并删除另一个。

示例:

如果列表包含以下两个项目:

06-07-2022T01:30:00,“一些随机说明” and 06-07-2022T01:35:00,“一些随机描述“

然后我们要删除其中一个,因为它们具有相同的描述并且在同一小时内。

但是,如果我们有这样的话:

06-07-2022T01:30:00,“一些随机说明” 06-07-07-2022T03:20:00,“一些随机说明”

然后,我们不想删除任何一个,因为它们不在同一小时内。

我该怎么做?

First of all, I have this object that I call MyObject;

public class MyObject{
    private google.protobuf.Timestamp timestamp;
    private String description;
}

Then I have this list:

List<MyObject> myList = new ArrayList<>();

Now let's imagine that myList contains 500 items. What I want, is to eliminate duplicates (identical descriptions) that occur within the same hour.

So two different items with identical descriptions should not both exist in the list within the same hour. If they do, we want to only keep one and delete the other.

Example:

If the list contains the following two items:

06-07-2022T01:30:00, "some random description" and 06-07-2022T01:35:00, "some random description"

Then we want to delete one of them because they have identical description and are within the same hour.

But if we have this:

06-07-2022T01:30:00, "some random description" and 06-07-2022T03:20:00, "some random description"

Then we don't want to delete any of them as they are not within the same hour.

How do I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不如归去 2025-02-20 18:52:05

根据您在评论中给出的澄清,我使用了 localdateTime 来简化示例条目并检索小时,但是我敢肯定 google.protobuf.timestamp 可以转换为适当的日期并提取其小时。

为了根据描述,日期和小时仅保留一个对象,我在POJO中添加了一个助手方法,以获取这些字段的串联,然后按其结果值进行分组以获取 MAP 每个键的位置(描述,日期和小时)只有一个对象关联。最后,我将 MAP 的值收集到 list 中。

List<MyObject> list = new ArrayList<>(List.of(
        new MyObject(LocalDateTime.parse("06-07-2022T01:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T01:35:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T03:20:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T04:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("06-07-2022T04:35:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("06-07-2022T06:20:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("08-07-2022T01:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description")
));

List<MyObject> listRes = list.stream()
        .collect(Collectors.toMap(
                obj -> obj.getDescrDateHour(),
                Function.identity(),
                (obj1, obj2) -> obj1
        ))
        .values()
        .stream().
        collect(Collectors.toList());

POJO类

class MyObject {
    private LocalDateTime timestamp;
    private String description;

    public MyObject(LocalDateTime timestamp, String description) {
        this.timestamp = timestamp;
        this.description = description;
    }

    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public String getDescription() {
        return description;
    }

    public String getDescrDateHour() {
        return description + timestamp.toLocalDate().toString() + timestamp.getHour();
    }

    @Override
    public String toString() {
        return timestamp + " - " + description;
    }
}

是用于测试代码

输出

Input: 
2022-07-06T01:30 - some random description
2022-07-06T01:35 - some random description
2022-07-06T03:20 - some random description
2022-07-06T04:30 - some random description2
2022-07-06T04:35 - some random description2
2022-07-06T06:20 - some random description2
2022-07-08T01:30 - some random description

Output: 
2022-07-06T04:30 - some random description2
2022-07-08T01:30 - some random description
2022-07-06T06:20 - some random description2
2022-07-06T03:20 - some random description
2022-07-06T01:30 - some random description

Based on the clarifications you've given in the comments I've used a LocalDateTime to simplify the sample entry and retrieve the hour, but I'm sure that google.protobuf.Timestamp can be converted to a proper date and extract its hour.

To keep only one object according to description, date and hour, I've added a helper method to your POJO to get a concatenation of these fields and then group by their result value in order to get a Map where to each key (description, date and hour) there is only one object associated. Lastly, I've collected the Map's values into a List.

List<MyObject> list = new ArrayList<>(List.of(
        new MyObject(LocalDateTime.parse("06-07-2022T01:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T01:35:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T03:20:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description"),
        new MyObject(LocalDateTime.parse("06-07-2022T04:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("06-07-2022T04:35:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("06-07-2022T06:20:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description2"),
        new MyObject(LocalDateTime.parse("08-07-2022T01:30:00", DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss")), "some random description")
));

List<MyObject> listRes = list.stream()
        .collect(Collectors.toMap(
                obj -> obj.getDescrDateHour(),
                Function.identity(),
                (obj1, obj2) -> obj1
        ))
        .values()
        .stream().
        collect(Collectors.toList());

POJO Class

class MyObject {
    private LocalDateTime timestamp;
    private String description;

    public MyObject(LocalDateTime timestamp, String description) {
        this.timestamp = timestamp;
        this.description = description;
    }

    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public String getDescription() {
        return description;
    }

    public String getDescrDateHour() {
        return description + timestamp.toLocalDate().toString() + timestamp.getHour();
    }

    @Override
    public String toString() {
        return timestamp + " - " + description;
    }
}

Here is a link to test the code

https://www.jdoodle.com/iembed/v0/sZV

Output

Input: 
2022-07-06T01:30 - some random description
2022-07-06T01:35 - some random description
2022-07-06T03:20 - some random description
2022-07-06T04:30 - some random description2
2022-07-06T04:35 - some random description2
2022-07-06T06:20 - some random description2
2022-07-08T01:30 - some random description

Output: 
2022-07-06T04:30 - some random description2
2022-07-08T01:30 - some random description
2022-07-06T06:20 - some random description2
2022-07-06T03:20 - some random description
2022-07-06T01:30 - some random description
合约呢 2025-02-20 18:52:05

一个安静的简单解决方案将是一个hashmap。您将描述用作钥匙和时间戳作为值。因此,您总是只保存最后一个时间戳将其保存到给定的描述并自动覆盖它。

如果要握住对象,我只会按日期对列表进行排序,然后填写hashmap并转换hashmap以再次列出。它不是最好的表现,但很容易。您可以通过函数 Java对功能样式进行分类

A quiet simple solution would be a HashMap. You use description as key and timestamp as value. So you always save only the last timestamp to given description and overwrite it automaticly.

If you want to hold your Object I would just sort the list by date, then fill in a HashMap and transform the HashMap to List again. It has not the best Performance, but its easy. You can Sort by Date with functional Java sorting a Collection in functional style

好听的两个字的网名 2025-02-20 18:52:05

您可以定义一个平等计算类的平等(或在 myobject 类中进行,具体取决于其实际代表的内容),并根据平等定义使用它来查找唯一值。在这种情况下,平等将意味着:相同的描述和相同的时间戳,每小时精度。

这是一个示例(可能需要一些调整,只是一个概念演示):


class UniqueDescriptionWithinHourIdentifier {

    // equals and hashCode could also be implemented in MyObject
    // if it's only purpose is data representation
    // but a separate class defines a more concrete abstraction

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHH");

    private Date timestamp;
    private String description;

    UniqueDescriptionWithinHourIdentifier(MyObject object) {
        timestamp = object.timestamp;
        description = object.description;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object == null || getClass() != object.getClass()) {
            return false;
        }
        var other = (UniqueDescriptionWithinHourIdentifier) object;
        return description.equals(other.description)
               // compare the timestamps however you want - format used for simplicity
               && DATE_FORMAT.format(timestamp)
                             .equals(DATE_FORMAT.format(other.timestamp));
    }

    @Override
    public int hashCode() {
        // cannot contain timestamp - a single hash bucket will contain multiple elements 
        // with the same definition and the equals method will filter them out
        return Objects.hashCode(description);
    }
}

class MyObjectService {

    // here a new list without duplicates is calculated  

    List<MyObject> withoutDuplicates(List<MyObject> objects) {
        return List.copyOf(objects.stream()
                                  .collect(toMap(UniqueDescriptionWithinHourIdentifier::new,
                                                 identity(),
                                                 (e1, e2) -> e1,
                                                 LinkedHashMap::new))
                                  .values());
    }

}

You could define an equality calculating class (or do it in the MyObject class, depending on what it actually represents) and use it to find unique values based on the equality definition. In this case equality would mean: same description and same timestamp with hourly precision.

Here's an example (might need some tweaking, just a concept presentation):


class UniqueDescriptionWithinHourIdentifier {

    // equals and hashCode could also be implemented in MyObject
    // if it's only purpose is data representation
    // but a separate class defines a more concrete abstraction

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHH");

    private Date timestamp;
    private String description;

    UniqueDescriptionWithinHourIdentifier(MyObject object) {
        timestamp = object.timestamp;
        description = object.description;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object == null || getClass() != object.getClass()) {
            return false;
        }
        var other = (UniqueDescriptionWithinHourIdentifier) object;
        return description.equals(other.description)
               // compare the timestamps however you want - format used for simplicity
               && DATE_FORMAT.format(timestamp)
                             .equals(DATE_FORMAT.format(other.timestamp));
    }

    @Override
    public int hashCode() {
        // cannot contain timestamp - a single hash bucket will contain multiple elements 
        // with the same definition and the equals method will filter them out
        return Objects.hashCode(description);
    }
}

class MyObjectService {

    // here a new list without duplicates is calculated  

    List<MyObject> withoutDuplicates(List<MyObject> objects) {
        return List.copyOf(objects.stream()
                                  .collect(toMap(UniqueDescriptionWithinHourIdentifier::new,
                                                 identity(),
                                                 (e1, e2) -> e1,
                                                 LinkedHashMap::new))
                                  .values());
    }

}
旧夏天 2025-02-20 18:52:05

添加等于&amp; HashCode 等于的MyObject类的方法具有以下逻辑:

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyObject other = (MyObject) obj;
                
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(timestamp);
        int hour1=calendar.HOUR;
        int date1 = calendar.DATE;
        calendar.setTime(other.timestamp);
        int hour2 = calendar.HOUR;
        int date2  =calendar.DATE;
        return Objects.equals(hour1, hour2) && Objects.equals(date1, date2);
    }

在这里,基本上,我正在检查2个对象是否具有相同的小时&amp;日期&amp;如果是这样,请忽略另一个对象。

一旦这样做,您就可以使用:

List<MyObject> myList = new ArrayList<>();
myList.stream().distinct().collect(Collectors.toList()); // returns you new distinct objects list.

请注意,您可以使用通过编辑器生成的 HashCode 的默认实现。 DISTICT()流的方法正在检查是否有等于&amp; HashCode 可用于基础流类。

注意:您可以将等于进行检查日,日期,月,年等,以验证确切的日期。

Add equals & hashcode method to your MyObject class with equals has some logic like below:

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyObject other = (MyObject) obj;
                
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(timestamp);
        int hour1=calendar.HOUR;
        int date1 = calendar.DATE;
        calendar.setTime(other.timestamp);
        int hour2 = calendar.HOUR;
        int date2  =calendar.DATE;
        return Objects.equals(hour1, hour2) && Objects.equals(date1, date2);
    }

Here, basically I am checking if 2 objects has same hour & date & if so, just ignore another object.

Once you do that, you can just use :

List<MyObject> myList = new ArrayList<>();
myList.stream().distinct().collect(Collectors.toList()); // returns you new distinct objects list.

Please note, you can use default implementation of hashCode generated via your editor for this case. distinct() method of stream is checking if you have equals & hashcode available for underlying streams class.

Note: you can extend equals to check day , date, month, year etc. for verifying exact date.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文