java - 根据列表中的一些对象属性删除重复项

标签 java list filter

我有一个列表集合,其中每个指标都包含多个属性,例如:metricName、命名空间、fleet、类型、组件、firstSeenTime、lastSeenTime 等。此列表中存在重复项,因此除firstSeenTime 和lastSeenTime 之外的所有属性都相同。我正在寻找一种优雅的方法来过滤此列表,并且仅在存在此类重复项时返回具有最新的lastSeenTime 的指标。

比这更好的东西:

private List<Metric> processResults(List<Metric metrics) {
    List<Metric> results = new ArrayList<>();

    for (Metric incomingMetric: metrics) {

        // We need to implement "contains" below so that only properties
        // other than the two dates are checked.
        if (results.contains(incomingMetric) { 
            int index = results.indexOf(incomingMetric);
            Metric existing = results.get(index); 
            if (incomingMetric.getLastSeen().after(existing.getLastSeen())) {
                results.set(index, metricName);
            } else {
                // do nothing, metric in results is already the latest 
            }
        } else {
            // add incomingMetric to results for the first time
            results.add(incomingMetric);
        }
    }

    return results;
}

results.contains 检查是通过迭代结果中的所有指标并检查每个对象是否与除两个日期之外的属性匹配来完成的。

还有什么比这更好的方法来兼顾优雅和性能呢?

最佳答案

在java中,比较事物的最优雅的方式是 Comparator界面。您应该使用以下方法删除重复项:

public List<Metric> removeDuplicates(List<Metric> metrics) {

    List<Metric> copy = new ArrayList<>(metrics);
    //first sort the metrics list from most recent to older
    Collections.sort(copy, new SortComparator());

    Set<Metric> set = new TreeSet<Metric>(new Comparator<Metric>() {

        @Override
        public int compare(Metric o1, Metric o2) {
            int result = 0;
            // compare the two metrics given your rules
            return result;
        }
    });

    for(Metric metric : copy) {
        set.add(metric);
    }

    List<Metric> result = Arrays.asList(set.toArray());
    return result;
 }

class SortComparator implements Comparator<Metric> {

    @Override
    public int compare(Metric o1, Metric o2) {
        int result = 0;
        if(o2.getLastSeenTime() != null && o1.getLastSeenTime() != null) {
            result = o2.getLastSeenTime().compareTo(o1.getLastSeenTime());
        }
        return result;
    }

}

这种方法的优点是您可以编写一系列比较器并提供 Factory在运行时选择比较指标并删除或不删除运行时条件中重复实例的最佳方式:

public void removeDuplicates(List<Metric> metrics, Comparator<Metric> comparator) {

    List<Metric> copy = new ArrayList<>(metrics);
    Collections.sort(copy, new SortComparator());

    Set<Metric> set = new TreeSet<Metric>(comparator);
    for(Metric metric : copy) {
        set.add(metric);
    }
    List<Object> result = Arrays.asList(set.toArray());
    return result;
 }

关于java - 根据列表中的一些对象属性删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46800173/

相关文章:

java - 控制 Linux 中 Java 独立运行的最大数量

python - 从嵌套字典中递归删除 None 值或 None 键

java - 如何在 Spring Boot Web 应用程序中配置 2 个单独的过滤器?

python - 从 python mysql 查询中过滤掉值

java - Wicket 按钮启用/禁用动态更新

java - List 中的 .add() 方法不适用于参数

java - 整数输入中的下划线导致java出错

java - 如何实现排序列表

python - 如何在CPython源代码中找到[::-1](在python中为反向列表)的实现

json - 使用 JQ 的多个过滤器