当前位置: 首页 > 知识库问答 >
问题:

如何根据Java列表中的maxDate记录进行分组和筛选

池庆
2023-03-14

我有一个java POJO收集metics如下:

public class Metric {

    Long metricId;
    Long resultKeyId;
    @NonNull DatasetType datasetType;
    @NonNull String datasetName;
    @NonNull String analyzerName;
    @NonNull String constraintAlias;
    @NonNull LocalDateTime entityDate;
    @NonNull long entityDurationSec;
    @NonNull Double metricValue;
    @NonNull String changedBy;
    Long jobId = 0L;
    Long codeArtifactId = 0L;
    LocalDateTime createdAt;
    LocalDateTime lastChanged;

}

我有一个来自上面pojo的度量列表,如List

现在,这个列表可以有多个项目,我只想用maxcreatedAt

SQL的表示方式如下:

select a.* from 
dataval_metric a 
join dataval_metric b 
on a.result_key_id=b.result_key_id 
and a.dataset_type=b.dataset_type 
and a.dataset_name=b.dataset_name 
and a.analyzer_name=b.analyzer_name 
and a.constraint_alias=b.constraint_alias  
where a.result_key_id = 434 
and a.mysql_row_created_at >= b. mysql_row_created_at;

正在寻找指针,以了解如何在Java中以高效的方式实现这一点


共有2个答案

王轶
2023-03-14

这样做的方法之一。

所以我们使用收集器。toMap,它将表示为记录的键映射为一个度量键(基本上这只是需要分组的字段的元组)到一个度量值。由于toMap不允许重复,我们还提供了merge函数,该函数始终在映射中保持最大createdDate的度量。

因此,我建议将getKey方法添加到Metric类中,以便它以记录或自定义类的形式返回密钥,从而覆盖equalshashCode

class Metric
{
  // ... all your fields
   
  record MetricKey(Long resultKeyId, String analyzerName,
       DatasetType datasetType, String datasetName, String constraintAlias) {  }
   
  public MetricKey getKey() {
    return new MetricKey(resultKeyId, datasetType, datasetName,
       analyzerName, constraintAlias);
  }

  public LocalDateTime getCreatedAt() {
    return createdAt;
  }
}

以及数据处理管道:

List<Metric> maximums = new ArrayList<>(metrics.stream().collect(
  Collectors.toMap(
    Metric::getKey,
    Function.identity(),
    (m1, m2) -> m1.createdAt > m2.createdAt ? m1 : m2))
  .values());
子车英达
2023-03-14

您必须使用gropingBy方法使用字段作为键。

关键在于:

  1. 清单:
Map<List<Object>, Optional<Metric>> map = metrics.stream()
        .collect(Collectors.groupingBy(m ->
                        List.of(m.getResultKeyId(),
                                m.getDatasetType(),
                                m.getDatasetName(),
                                m.getAnalyzerName(),
                                m.getConstraintAlias()),
                Collectors.maxBy(Comparator.comparing(Metric::getCreatedAt))));
Map<Metric, Optional<Metric>> map = metrics.stream()
        .collect(Collectors.groupingBy(m -> m,
                Collectors.maxBy(Comparator.comparing(Metric::getCreatedAt))));
Map<Quintet, Optional<Metric>> map = metrics.stream()
        .collect(Collectors.groupingBy(m ->
                        new Quintet(m.getResultKeyId(),
                                m.getDatasetType(),
                                m.getDatasetName(),
                                m.getAnalyzerName(),
                                m.getConstraintAlias()),
                Collectors.maxBy(Comparator.comparing(Metric::getCreatedAt))));
 类似资料:
  • 我想通过列表中的第一个元素进行过滤,然后通过第二个元素进行分组。 在使用Java Stream获得平均值之前,我过滤了第一个元素,即index。这样做合适吗?

  • 我创建了一个用户,他属于一个名为Security的组。在Camunda modeler中,我明确地将任务分配给了组设施。然而,在运行应用程序时,我可以看到属于组安全性的用户可以查看并声明分配给组设施的任务。 如何确保任务列表仅显示分配给特定用户组的任务?目标是用户可以查看另一个组的任务。

  • 我有以下模式- [名称:StringType,Grades:ArrayType(StructType(StructField(subject_grades),ArrayType(StructType(StructField(subject,StringType,false)),StructField(grade,LongType,false) 我想在数组中的subject字段上,该数组位于grad

  • 我有以下表在PostgreSQL 11.0 我想过滤上表,这样,如果col2和col4相等,只应选择此匹配项,并排除下面两行。当col2和col4不相等时,应该保留col2=col3的行。 所需的输出是: 我正在尝试下面的问题,到目前为止没有成功。 但这将包括已经有匹配的行,我希望在最终输出中排除这些行。

  • 我正在尝试根据第二个列表中的值筛选对象列表。 现在我想移除列表A的项目,该项目的ID在列表B中可用。 null null 感谢任何帮助

  • 我有一个pandas数据帧像: 我想按第一列进行分组,并将第二列作为行中的列表: