如何通过列表

时间:2017-05-16 13:56:45

标签: java java-8 java-stream

我有过滤器personCountFilter=3,并且列表如下:

Rate{ PersonCount:1, LOS:1}
Rate{ PersonCount:1, LOS:2}
Rate{ PersonCount:1, LOS:3}
Rate{ PersonCount:2, LOS:1}
Rate{ PersonCount:2, LOS:2}
Rate{ PersonCount:2, LOS:3}
Rate{ PersonCount:3, LOS:2}
Rate{ PersonCount:3, LOS:4}
Rate{ PersonCount:3, LOS:5}
Rate{ PersonCount:3, LOS:6}
Rate{ PersonCount:4, LOS:3}
Rate{ PersonCount:5, LOS:7}
Rate{ PersonCount:6, LOS:7}

过滤我的预期后:

Rate{ PersonCount:2, LOS:1}
Rate{ PersonCount:3, LOS:2}
Rate{ PersonCount:4, LOS:3}
Rate{ PersonCount:3, LOS:4}
Rate{ PersonCount:3, LOS:5}
Rate{ PersonCount:3, LOS:6}
Rate{ PersonCount:5, LOS:7}

如何在按LOS分组后获取值,如果personCount匹配过滤器得到此值,如果不匹配,则最接近personCountFilter,更大personCountFilter首先

我尝试使用

HashSet<Rate> testSet = rates.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(Rate::getLengthOfStayCount,
                                Function.identity(),
                                (previous, current) ->
                                {
                                    return previous.getPersonCount() > 
                                           current.getPersonCount() ? previous : current;
                                }),
                        map ->
                        {
                            HashSet<Rate> set = new HashSet<>();
                            set.addAll(map.values());
                            return set;
                        }));

但它返回

Rate{ PersonCount:2, LOS:1}
Rate{ PersonCount:3, LOS:2}
Rate{ PersonCount:4, LOS:3}
Rate{ PersonCount:3, LOS:4}
Rate{ PersonCount:3, LOS:5}
Rate{ PersonCount:3, LOS:6}
Rate{ PersonCount:6, LOS:7}

当按LOS分组后,当前它获得最大人数。

2 个答案:

答案 0 :(得分:0)

我无法使用您在问题中提供的信息测试以下代码(了解如何制作一个 Minimal, Complete, and Verifiable example您的下一个问题),但我认为这样的事情对您有用:

HashSet<Rate> testSet = rates.stream()
        .collect(Collectors.collectingAndThen(
                Collectors.toMap(Rate::getLengthOfStayCount,
                        Function.identity(),
                        (previous, current) ->
                        {
                            int diff1 = Math.abs(personCountFilter - previous.getPersonCount());
                            int diff2 = Math.abs(personCountFilter - current.getPersonCount());
                            if (diff1 > diff2) {
                                return current;
                            } else if (diff1 < diff2) {
                                return previous;
                            } else if (diff1 == diff2) {
                                return previous.getPersonCount() <= current.getPersonCount() ? current : previous;
                            }
                        }),
                map -> new HashSet<>(map.values())
                    ));

答案 1 :(得分:0)

如果我理解正确,您希望获得每个组的元素,其personCount属性最接近数字3,并且在出现平局时优先选择较高的数字。

您可以使用

来实现它
HashSet<Rate> testSet = rates.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.toMap(Rate::getLengthOfStayCount,
                Function.identity(),
                BinaryOperator.minBy(
                   Comparator.comparingDouble(rate -> Math.abs(rate.getPersonCount()-3.1)))
        ),
        map -> new HashSet<>(map.values())
    ));

Math.abs(rate.getPersonCount()-3)是您的目标号码3的距离,获得该值最小值的元素将获得最接近的值。通过简单地使用3.1而不是3,我们在平局的情况下优先选择更高的数字(假设您的属性具有整数类型)。