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

从列表对象创建一个SortedMap,其值表示为映射到特定键的N个最低对象属性的列表

黎阳冰
2023-03-14

我正在使用一个CSV文件,其中包含一些有关事故的信息。

我创建了事故类型:

private Integer driverAge;
private Integer vehicleAge;

public Accident(Integer driverAge, Integer vehicleAge) {
    this.driverAge = driverAge;
    this.vehicleAge = vehicleAge;
}

我还创建了一个函数,可以读取所有CSV文件,将所有事故转换为列表

private List<Accident> accidents;

public AccidentArchive(List<Accident> accidents) {
    this.accidents = accidents;
}

因此,我们正在处理我还不完全理解的流,我一直在做这个练习,我必须生成一个返回排序映射的函数

public SortedMap<Integer, List<Integer>> getNMinVehicleAgesPerDriverAge(Integer n) {
    return getAccidents().stream().
...

我尝试使用Collectors.toMap()Collectors.toList()以某种方式使其工作,但我不知道如何做到这一点。

共有1个答案

齐高阳
2023-03-14

您可以使用一种风格的groupingBy(),它需要三个参数:分类器函数、供应商映射工厂(允许指定映射的结果类型)和下游收集器。

作为groupingBy()的下游收集器,您可以利用映射()和仅保留n最低车辆年龄值的自定义收集器的组合与每个driverage相关联:

public SortedMap<Integer, List<Integer>> getNMinVehicleAgesPerDriverAge(Integer n) {
    return getAccidents().stream()
        .collect(Collectors.groupingBy(Accident::getDriverAge,
            TreeMap::new,
            Collectors.mapping(Accident::getVehicleAge, 
                getMaxN(n, Comparator.<Integer>reverseOrder()))));
}

下面提供的方法负责根据所提供的结果列表的最大大小和比较器生成自定义收集器。答案中详细解释了其背后的逻辑:

public static <T> Collector<T, ?, List<T>> getMaxN(int size, Comparator<T> comparator) {
        
    return Collector.of(
        () -> new PriorityQueue<>(comparator),
        (Queue<T> queue, T next) -> tryAdd(queue, next, comparator, size),
        (Queue<T> left, Queue<T> right) -> {
            right.forEach(next -> tryAdd(left, next, comparator, size));
            return left;
        },
        (Queue<T> queue) -> queue.stream().toList(),
        Collector.Characteristics.UNORDERED);
}
    
public static <T> void tryAdd(Queue<T> queue, T next, Comparator<T> comparator, int size) {
    if (queue.size() == size && comparator.compare(next, queue.element()) < 0) queue.remove(); // if next value is less than the smallest element in the queue and max size has been exceeded the largest element needs to be removed from the queue
    if (queue.size() < size) queue.add(next);
}

顺便说一下,如果您的作业没有指定使用分类地图作为返回类型的要求。最好使用NavigableMap接口,它定义了更广泛的方法。

 类似资料:
  • 问题内容: 我的ViewValue类定义如下: 在我的代码中,我需要将ViewValue实例列表转换为包含来自相应ViewValue的id字段值的列表。 我用foreach循环来做: } 有没有更好的方法来解决这个问题? 问题答案: 编辑:此答案基于以下想法:您需要对代码中其他位置的不同实体和不同属性执行类似的操作。如果您 只需 要按ID将ViewValues列表转换为Longs列表,则请坚持使用

  • 我正在使用一个CSV文件,其中包含一些有关事故的信息。现在我已经创建了事故类型: 我还创建了一个函数,可以读取所有csv文件,将所有事故转换为列表 因此,我们正在处理我还不完全理解的流,我一直在做这个练习,我必须创建一个返回SortedMap的函数 我试过使用收集器。toMap()和收集器。toList()以某种方式使其工作,但我不知道如何做。我已经搜索了一段时间,但我没有找到任何与我的情况类似的

  • 当遍历ACROD时,有一个列表,并希望将该列表中的第一个对象映射到我的域对象。 @mapping(source=“insurancesvcrqs[0].policyquoteinqrqsaddrqsandpolicyquoteinqrqs[0].productues[0].generalpartyinfo.nameinfos[0].commlname.commericalname”,target=

  • 假设我有这样的映射: 现在,我需要将子列表映射到子列表,但它们都有相同的父对象。我希望这样做: 但不管用,有机会做吗?

  • 问题内容: 我想使用Java 8技巧在一行中执行以下操作。 给定此对象定义: 和a ,我想得到a ,它是第一个列表中所有s对象的列表- 顺序相同。 我可以使用Java中的循环来做到这一点,但我相信Java8中应该有一个单行lambda可以做到这一点。我无法在线找到解决方案。也许我没有使用正确的搜索词。 有人可以为这种转换建议一个lambda或另一种线吗? 问题答案: 这应该可以解决问题: 也就是说

  • 我可以在Java中使用循环来实现这一点,但我认为在Java8中应该有一个一行程序lambda来实现这一点。我无法在网上找到解决方案。也许我没有使用正确的搜索词。 有人能为这个转换提出一个lambda或另一个一行程序吗?