how to convert forEach to lambda

前端 未结 3 383
旧时难觅i
旧时难觅i 2021-01-15 09:02
Iterator rateIt = rates.iterator();
int lastRateOBP = 0;
while (rateIt.hasNext())
{
    Rate rate = rateIt.next();
    int currentOBP = rate.getPersonCou         


        
相关标签:
3条回答
  • 2021-01-15 09:51

    This should work if your Rate type has natural ordering (i.e. implements Comparable):

    List<Rate> l = rates.stream()
                                 .distinct()
                                 .sorted()
                                 .collect(Collectors.toList());
    

    If not, use a lambda as a custom comparator:

    List<Rate> l = rates.stream()
                                 .distinct()
                                 .sorted( (r1,r2) -> ...some code to compare two rates... )
                                 .collect(Collectors.toList());
    

    It may be possible to remove the call to sorted if you just need to remove duplicates.

    0 讨论(0)
  • 2021-01-15 09:54

    If you really want distinct and sorted as you say in your comments, than it is as simple as :

    TreeSet<Rate> sorted = rates.stream()
                      .collect(Collectors.toCollection(() -> 
                       new TreeSet<>(Comparator.comparing(Rate::getPersonCount))));
    

    But notice that in your example with an iterator you are not removing duplicates, but only duplicates that are continuous (I've exemplified that in the comment to your question).

    EDIT

    It seems that you want distinct by a Function; or in simpler words you want distinct elements by personCount, but in case of a clash you want to take the max pos.

    Such a thing is not yet available in jdk. But it might be, see this.

    Since you want them sorted and distinct by key, we can emulate that with:

     Collection<Rate> sorted = rates.stream()
                .collect(Collectors.toMap(Rate::getPersonCount,
                        Function.identity(),
                        (left, right) -> {
                            return left.getLos() > right.getLos() ? left : right;
                        },
                        TreeMap::new))
                .values();
    
        System.out.println(sorted);
    

    On the other hand if you absolutely need to return a TreeSet to actually denote that this are unique elements and sorted:

     TreeSet<Rate> sorted = rates.stream()
                .collect(Collectors.collectingAndThen(
    
                        Collectors.toMap(Rate::getPersonCount,
                                Function.identity(),
                                (left, right) -> {
                                    return left.getLos() > right.getLos() ? left : right;
                                },
                                TreeMap::new),
                        map -> {
                            TreeSet<Rate> set = new TreeSet<>(Comparator.comparing(Rate::getPersonCount));
                            set.addAll(map.values());
                            return set;
                        }));
    
    0 讨论(0)
  • 2021-01-15 09:57

    The simplest solution is

    Set<Integer> seen = new HashSet<>();
    rates.removeIf(rate -> !seen.add(rate.getPersonCount()));
    

    it utilizes the fact that Set.add will return false if the value is already in the Set, i.e. has been already encountered. Since these are the elements you want to remove, all you have to do is negating it.

    If keeping an arbitrary Rate instance for each group with the same person count is sufficient, there is no sorting needed for this solution.

    Like with your original Iterator-based solution, it relies on the mutability of your original Collection.

    0 讨论(0)
提交回复
热议问题