首页 > 解决方案 > 找到 N 个通过给定条件的第一个元素:求和给定的数字

问题描述

我有Pocket实例列表

List<Pocket> pockets;

其中Pocket类如下所示:

public class Pocket {
    String name;
    Double amount;
}

口袋列表示例:

[
    {"pocket1", 280},
    {"pocket2", 320},
    {"pocket3", 100},
    {"pocket4", 125},
    {"pocket5", 150},
    {"pocket6", 175}
]

我需要从给定的口袋列表中找到n可以一起提供N(例如 650 个)的第一个口袋。如果最后一个口袋amount比需要的大,这个口袋应该分成两个口袋,结果列表应该只包含一个与前面的n - 1口袋一起给出的部分N

例如,我需要按顺序排列的口袋列表,就像 source list 一样,它一起给出了 amount 650。请注意,口袋被分割了,最后一个口袋3-rd只返回了一半:amount

[
    {"pocket1", 280},
    {"pocket2", 320},
    {"pocket3", 50}
]

如何实现它Java Streams

标签: javalambdacollectionsjava-8java-stream

解决方案


你可以使用flatMapandStream来做到这一点。请参见下面的示例:

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

public class Lambda {

    public static void main(String[] args) {
        List<Pocket> pockets = Arrays.asList(
            new Pocket("pocket1", 280D),
            new Pocket("pocket2", 320D),
            new Pocket("pocket3", 100D),
            new Pocket("pocket4", 50D));

        System.out.println("Filtered");
        pockets.stream()
            .flatMap(new SplitFunction(651))
            .forEach(System.out::println);

        System.out.println("Original");
        pockets.forEach(System.out::println);
    }
}


class SplitFunction implements Function<Pocket, Stream<Pocket>> {

private double max;

public SplitFunction(double max) {
    this.max = max;
}

@Override
public Stream<Pocket> apply(Pocket pocket) {
    if (Double.compare(max, pocket.amount) >= 0) {
        max -= pocket.amount;
        return Stream.of(pocket);
    } else if (Double.compare(max, 0.0) > 0) {
        Pocket lastPocket = new Pocket(pocket.name, max);
        max = 0;

        return Stream.of(lastPocket);
    }
    return Stream.empty();
}
}

上面的代码打印:

Filtered
Pocket{name='pocket1', amount=280.0}
Pocket{name='pocket2', amount=320.0}
Pocket{name='pocket3', amount=51.0}
Original
Pocket{name='pocket1', amount=280.0}
Pocket{name='pocket2', amount=320.0}
Pocket{name='pocket3', amount=100.0}
Pocket{name='pocket4', amount=50.0}

推荐阅读