how can i get value through complex logic from list

谁说胖子不能爱 提交于 2019-12-25 17:26:19

问题


I have filter personCountFilter=3, and have list as below:

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}

After filter my expected:

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}

how can I get value after grouping by LOS, and if personCount matched filter get this one, if not matched, get closest to personCountFilter, bigger personCountFilter first

I tried to use

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;
                        }));

but it returns

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}

Current it gets max personCount when after grouping by LOS


回答1:


I was unable to test the following code with the information you have provided in the question (learn how to make a Minimal, Complete, and Verifiable example for your next question), but I think something like this should work for you:

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())
                    ));



回答2:


If I understand you correctly, you want to get the element of each group, which has the personCount property closest to the number 3, with preference to the higher number in case of a tie.

You may achieve it using

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) is the distance to your goal number 3, getting the element with the minimum of that value will get the closest. By simply using 3.1 instead of 3, we achieve preference to higher numbers in case of a tie (assuming that you property has an integer type).



来源:https://stackoverflow.com/questions/44003534/how-can-i-get-value-through-complex-logic-from-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!