【问题标题】:Create and find highest value in subarraylist在子数组列表中创建并查找最大值
【发布时间】:2022-01-03 23:36:59
【问题描述】:

我有一个 Excel 工作表中的单元格数组列表。我想从我实际拥有的单元格数组列表中创建大小为 50 的子数组列表,从索引 1590 开始,以 size()-700 结束。

我想从每个子数组列表中获取最大的数字并将其放入新的数组列表中。在新的 Arraylist 中应该只有每个 subarraylist 的最大值。

输入数据是我的单元格数组列表。

使用此代码,我得到了 50 多个数字,但它并不总是最高值。有人有想法吗?

这是我的代码:

int partitionSize = 50;

List<List<Cell>> partitions = new ArrayList<>();
List <Cell> high = new ArrayList();
Cell max = data.get(1590);

for (int i = 1590; i < data.size()-700; i += partitionSize) {
    partitions.add(data.subList(i, Math.min(i + partitionSize, data.size()-700)));
}

for (List<Cell> list : partitions) {
    for (int i = 1; i < list.size(); i++) {
        if (list.get(i).getNumericCellValue() > max.getNumericCellValue()) {
            max = list.get(i);
        }
        high.add(max);
    }
}

【问题讨论】:

    标签: java list arraylist collections sub-array


    【解决方案1】:

    可以使用IntStream::iterate生成分区列表:

    int start = 1590;
    int end = data.size() - 700;
    int size = 50;
    List<List<Cell>> partitions = IntStream
        .iterate(start, i -> i < end, i -> i + size) // IntStream
        .mapToObj(i -> data.subList(i, Math.min(i + size, end)))
        .collect(Collectors.toList())
    ;
    

    然后可以按如下方式检索具有最大值的单元格列表:

    List<Cell> maxPerRange = partitions
        .stream() // Stream<List<Cell>>
        .map(list -> list.stream() // Stream<Cell>
                         .max(Comparator.comparing(Cell::getNumericCellValue))
                         .get()
        )
        .collect(Collectors.toList());
    

    类似地,可以创建最大值列表,而无需将输入数据显式拆分为子列表,只需使用类似于嵌套循环的适当范围:

    List<Cell> maxPerRange = IntStream
        .iterate(start, i -> i < end, i -> i + size) // IntStream
        .mapToObj(i -> IntStream.range(i, Math.min(i + size, end))
                .mapToObj(data::get)
                .max(Comparator.comparing(Cell::getNumericCellValue))
                .get()
        )
        .collect(Collectors.toList());
    

    【讨论】:

    • 非常感谢,这对我帮助很大。它不知道 IntStream API。我喜欢这两种解决方案,最后一个非常紧凑,第一个也很棒!
    • 这个特定版本的IntStream/Stream::iterate方法是在Java 9中引入的
    【解决方案2】:

    您可以利用 Stream API。

    例如:

    List<List<Integer>> partitions = new ArrayList<>();
    List<Integer> high = partitions.stream()
        .map(partition -> partition.stream().max(Integer::compareTo))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());
    

    【讨论】:

    • 我应该做什么而不是可选我应该把类型而不是和isPresent?我的 Arraylist 的类型是 Cell 没有 compareTo 方法。
    • 您可以将Integer::compareTo 替换为Cell 的两个实例的比较方法,但保留Optional::isPresent。抱歉,我应该考虑一下:Java 对您来说是新事物吗?
    • 是的,这对我来说是新的,对你的评论 uo p 对我有很大帮助,但感谢你的建议 :)
    • @Nando94 抱歉,我对您的最后评论感到困惑。我的解决方案对您有用还是您需要更多帮助?
    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 2023-01-02
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    相关资源
    最近更新 更多